Вход | Регистрация
 

SQL 2005 и ВыбратьПодчиненныеДокументы()

Ø [Emvika, 07.04.09 - 20:02]
SQL 2005 и ВыбратьПодчиненныеДокументы()
Я
   ДенисЧ
 
03.04.09 - 15:22
Вещь известная, но...

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

Кто-нибудь решил эту проблему?
   leshikkam
 
1 - 03.04.09 - 15:24
(0) Мне помогала полная переиндексация средствами SQL и обновление статистики.
Хотя я видел что не всегда с решались проблемы у людей теми методами которые я указал. Один из вариантов - прямой запрос.
   ДенисЧ
 
2 - 03.04.09 - 15:25
(1) Индексация и статистики обновляются регулярно...
А прямой запрос - уже думаем. Просто много мест, где переписывать...
   leshikkam
 
3 - 03.04.09 - 15:26
А ты сделай класс наследник от Документ ;)
   ДенисЧ
 
4 - 03.04.09 - 15:26
(3) У меня нет 1с++
   leshikkam
 
5 - 03.04.09 - 15:28
(4) Это диагноз?
Если нет - то значит можно поставить и использовать, ну а если не предполагается использование, то можно использовать решение от softpoint.
   v_rtex
 
6 - 03.04.09 - 15:29
вот бы никогда не подумал, что у ДенисаЧ нет 1с++ -)
ставь.. не пожалеешь..
   mikecool
 
7 - 03.04.09 - 15:30
(0) используя 1с++ и оператор WITH можно накропать неплохую серверную функцию, которая будет выбирать тебе дерево
   ДенисЧ
 
8 - 03.04.09 - 15:31
(6) нет и в ближайшее время не будет. Ибо в _нашей_ среде она работает не очень стабильно.
Нам хватает радуги и адо.
   leshikkam
 
9 - 03.04.09 - 15:31
(7) буквально позавчера её выкладывали
   ДенисЧ
 
10 - 03.04.09 - 15:32
(7) Я знаю, что её можно накропать. И будем это делать. Но сначала хотелось исправить системные средства.
   toypaul
 
11 - 03.04.09 - 15:32
а можно с помощью ToySQL перехватить соот-щий запрос и заменить его на правильный :)
   Sadovnikov
 
12 - 03.04.09 - 15:44
(8) Радуга, как раз, гораздо более нестабильной была, чем 1С++ сейчас.
   zaki
 
13 - 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с но на общие журналы это не будет влиять, они будут тормозить также, а во втором случае все будет работать на всей базе без изменения кода
   zaki
 
14 - 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;
    КонецЕсли;
КонецФункции
   zaki
 
15 - 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();
   trdm
 
16 - 03.04.09 - 19:26
браво...
   toypaul
 
17 - 03.04.09 - 19:28
(15) и работает? по идее 1С ожидает в запросе на 2 параметра больше. так что ошибка должна быть. ИМХО
   toypaul
 
18 - 03.04.09 - 19:31
кривой как-то форум код обрезал. но я успел заметить, что в измененном запросе убран отбор по периоду. это по-моему неверно. или все-таки там стоит отбор по дате из _1SJOURN?
   zaki
 
19 - 03.04.09 - 19:37
(17) Да работает все это, убран именно выбор периода, оптимизатору SQL 2005 имено оно сносит башку в 1с если даты начала и конца пустые туда пихается что то типа 1700 год начал и 9999 конец он начинает из за этого тупо сканировать таблицы, если народ лазить по журналу и подчиненым журналам и еще отчеты юзает то сервак тупо вешается
   toypaul
 
20 - 03.04.09 - 19:40
(19) гм...а если подчиненные надо отобрать за период?
   toypaul
 
21 - 03.04.09 - 19:42
(19) кстати да - косяк 1С-ников. по идее и СКЛ 2000 мог бы также поступить. поэтому видимо всегда лучше указывать период при выборе подчиненных.
   trdm
 
22 - 03.04.09 - 19:42
(20) тогда вероятно вариант №1
   zaki
 
23 - 03.04.09 - 19:44
(20) Мне проще после ВыбратьПодчиненныеДокументы() проверить дату дока чем тормоза все системы, в отчетах я юзаю вариант 1


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Ветка сдана в архив. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.