Имя: Пароль:
1C
 
SQL 2005 и ВыбратьПодчиненныеДокументы()
Ø (Emvika 07.04.2009 20:02)
0 ДенисЧ
 
03.04.09
15:22
Вещь известная, но...

Очень много времени занимает ВыбратьПодчиненныеДокументы()...
Журнал подчиненных в конфе есть.
Очевидно, что sql неправильно строит план запроса...

Кто-нибудь решил эту проблему?
1 leshikkam
 
03.04.09
15:24
(0) Мне помогала полная переиндексация средствами SQL и обновление статистики.
Хотя я видел что не всегда с решались проблемы у людей теми методами которые я указал. Один из вариантов - прямой запрос.
2 ДенисЧ
 
03.04.09
15:25
(1) Индексация и статистики обновляются регулярно...
А прямой запрос - уже думаем. Просто много мест, где переписывать...
3 leshikkam
 
03.04.09
15:26
А ты сделай класс наследник от Документ ;)
4 ДенисЧ
 
03.04.09
15:26
(3) У меня нет 1с++
5 leshikkam
 
03.04.09
15:28
(4) Это диагноз?
Если нет - то значит можно поставить и использовать, ну а если не предполагается использование, то можно использовать решение от softpoint.
6 v_rtex
 
03.04.09
15:29
вот бы никогда не подумал, что у ДенисаЧ нет 1с++ -)
ставь.. не пожалеешь..
7 mikecool
 
03.04.09
15:30
(0) используя 1с++ и оператор WITH можно накропать неплохую серверную функцию, которая будет выбирать тебе дерево
8 ДенисЧ
 
03.04.09
15:31
(6) нет и в ближайшее время не будет. Ибо в _нашей_ среде она работает не очень стабильно.
Нам хватает радуги и адо.
9 leshikkam
 
03.04.09
15:31
(7) буквально позавчера её выкладывали
10 ДенисЧ
 
03.04.09
15:32
(7) Я знаю, что её можно накропать. И будем это делать. Но сначала хотелось исправить системные средства.
11 toypaul
 
гуру
03.04.09
15:32
а можно с помощью ToySQL перехватить соот-щий запрос и заменить его на правильный :)
12 Sadovnikov
 
03.04.09
15:44
(8) Радуга, как раз, гораздо более нестабильной была, чем 1С++ сейчас.
13 zaki
 
03.04.09
19:08
Проблема в этом запросе
"Select JOURN.* from _1SJOURN JOURN(NOLOCK INDEX=ACDATETIME), _1SCRDOC CRDOC(NOLOCK INDEX=PARENT) where JOURN.DATE_TIME_IDDOC=CRDOC.CHILD_DATE_TIME_IDDOC and CRDOC.MDID=? and CRDOC.PARENTVAL=? and CRDOC.CHILD_DATE_TIME_IDDOC>=? and CRDOC.CHILD_DATE_TIME_IDDOC<=? order by CRDOC.MDID, CRDOC.PARENTVAL, CRDOC.CHILD_DATE_TIME_IDDOC"

а именно вот это "CRDOC.CHILD_DATE_TIME_IDDOC>=? and CRDOC.CHILD_DATE_TIME_IDDOC<=?" сбивает оптимизатор с толку из за того что 1с все пихает через параметризованную процедуру для вывода данных через курсор  

Решение есть или написать свою процедуру на прямых запросах или исправить сам запрос, в первом варианте решение можно реализовать только в коде 1с но на общие журналы это не будет влиять, они будут тормозить также, а во втором случае все будет работать на всей базе без изменения кода
14 zaki
 
03.04.09
19:17
Решение №1 юзается 1с++
----
Функция глВыбратьПодчиненныеДокументы(ДатаНач,ДатаКон,Док,ТипДок="",Проведен="") Экспорт
   СкульЗапрос="
   |SELECT
   | TabJ.IDDOC,
   | TabJ.IDDOCDEF
   |FROM
   | _1SCRDOC As TabRod(NOLOCK)
   |INNER JOIN
   | _1SJOURN As TabJ(NOLOCK) ON (TabRod.CHILDID = TabJ.IDDOC)
   |WHERE
   | TabRod.MDID = 0 -- только документы, без граф отбора
   | AND TabRod.PARENTVAL = '"+Сервис1С.ЗначениеВСамуюДлиннуюСтрокуБД(Док.ТекущийДокумент())+"'
   |";
   Если ПустоеЗначение(ДатаНач)=0 Тогда
       СкульЗапрос=СкульЗапрос+"
       |and DATE_TIME_IDDOC>='"+Сервис1С.ПолучитьСтрИзДаты(ДатаНач)+"'
       |";
   КонецЕсли;
   Если ПустоеЗначение(ДатаКон)=0 Тогда
       СкульЗапрос=СкульЗапрос+"
       |and DATE_TIME_IDDOC<'"+Сервис1С.ПолучитьСтрИзДаты(ДатаКон+1)+"'
       |";
   КонецЕсли;
   Если ТипДок<>"" Тогда
       СкульЗапрос=СкульЗапрос+"
       |and IDDOCDEF='"+Сервис1С.ИДДокумента(ТипДок)+"'
       |";
   КонецЕсли;
   Если Проведен=1 Тогда
       СкульЗапрос=СкульЗапрос+"
       |and CLOSED=1
       |";
   КонецЕсли;
   СкульЗапрос=СкульЗапрос+"
   |ORDER BY
   |TabRod.CHILD_DATE_TIME_IDDOC
   |";
   ТЗЗапрос =СоздатьОбъект("ТаблицаЗначений");
   ТЗ =СоздатьОбъект("ТаблицаЗначений");
   ТЗ.НоваяКолонка("Док");
   Запрос1С.Подготовить(СкульЗапрос);
   Если Запрос1С.Открыть()=1 Тогда
       Запрос1С.ПолучитьРезультатыВ_ТЗ(ТЗЗапрос,1);
       ТЗЗапрос.ВыбратьСтроки();
       Пока ТЗЗапрос.ПолучитьСтроку() = 1 Цикл
           ТЗ.НоваяСтрока();
           ТЗ.Док=Сервис1С.ЗначениеИзСтрокиБД(12,ТЗЗапрос.IDDOCDEF,ТЗЗапрос.IDDOC);
       КонецЦикла;
       Запрос1С.Закрыть();
       Возврат ТЗ;
   Иначе
       Возврат 0;
   КонецЕсли;
КонецФункции
15 zaki
 
03.04.09
19:19
Решение №2 с помощью перехватчика запросов vk_Hook1C.dll от romix немного подправленный мной  

---
ЗагрузитьВнешнююКомпоненту("vk_Hook1C.dll");

vk_hook=СоздатьОбъект("Addin.vk_Hook1C");
vk_hook.ПерехватSQLPrepare();
           
vk_hook.ТекстSQL="Select JOURN.* from _1SJOURN JOURN(NOLOCK INDEX=ACDATETIME), _1SCRDOC CRDOC(NOLOCK INDEX=PARENT) where JOURN.DATE_TIME_IDDOC=CRDOC.CHILD_DATE_TIME_IDDOC and CRDOC.MDID=? and CRDOC.PARENTVAL=? and CRDOC.CHILD_DATE_TIME_IDDOC>=? and CRDOC.CHILD_DATE_TIME_IDDOC<=? order by CRDOC.MDID, CRDOC.PARENTVAL, CRDOC.CHILD_DATE_TIME_IDDOC";
           
vk_hook.НовыйSQL="Select JOURN.* from _1SJOURN JOURN(NOLOCK), _1SCRDOC CRDOC(NOLOCK) where JOURN.DATE_TIME_IDDOC=CRDOC.CHILD_DATE_TIME_IDDOC and CRDOC.MDID=? and CRDOC.PARENTVAL=? order by CRDOC.MDID, CRDOC.PARENTVAL, CRDOC.CHILD_DATE_TIME_IDDOC";

vk_hook.УстановитьЗаменуSQL();
16 trdm
 
03.04.09
19:26
браво...
17 toypaul
 
гуру
03.04.09
19:28
(15) и работает? по идее 1С ожидает в запросе на 2 параметра больше. так что ошибка должна быть. ИМХО
18 toypaul
 
гуру
03.04.09
19:31
кривой как-то форум код обрезал. но я успел заметить, что в измененном запросе убран отбор по периоду. это по-моему неверно. или все-таки там стоит отбор по дате из _1SJOURN?
19 zaki
 
03.04.09
19:37
(17) Да работает все это, убран именно выбор периода, оптимизатору SQL 2005 имено оно сносит башку в 1с если даты начала и конца пустые туда пихается что то типа 1700 год начал и 9999 конец он начинает из за этого тупо сканировать таблицы, если народ лазить по журналу и подчиненым журналам и еще отчеты юзает то сервак тупо вешается
20 toypaul
 
гуру
03.04.09
19:40
(19) гм...а если подчиненные надо отобрать за период?
21 toypaul
 
гуру
03.04.09
19:42
(19) кстати да - косяк 1С-ников. по идее и СКЛ 2000 мог бы также поступить. поэтому видимо всегда лучше указывать период при выборе подчиненных.
22 trdm
 
03.04.09
19:42
(20) тогда вероятно вариант №1
23 zaki
 
03.04.09
19:44
(20) Мне проще после ВыбратьПодчиненныеДокументы() проверить дату дока чем тормоза все системы, в отчетах я юзаю вариант 1