Имя: Пароль:
1C
1C 7.7
v7: SQLite медленней, чем стандартная выборка
0 Sam1C
 
08.11.18
17:12
Нужно получение последнего документа определенного вида по контрагенту (имеется графа отбора):
1) Стандарт:
Док = СоздатьОбъект("Документ");
Док.ОбратныйПорядок(1);       Док.ВыбратьПоЗначению(,ТекущаяДата(),"Контрагент",пКонтрагент);
Пока Док.ПолучитьДокумент() = 1 Цикл  
    Если Док.Вид() <> пВид Тогда
        продолжить;    
    КонецЕсли;
   Если Док.ПолучитьАтрибут(ИД_Контрагент) = пКонтрагент Тогда
                прервать;
  КонецЕсли;
КонецЦикла;      
2) Запрос:
ТекстЗапроса = "SELECT
        |  Док.IDDOC [Документ  $Документ." + пВид + "]
        |, Док.Контрагент [Контрагент $Справочник.Контрагенты]
        |FROM [Документ." + пВид + "]  AS Док
        |WHERE  (Док.Контрагент = :ВыбКонтрагент)  
        |ORDER BY Док.IDDOC DESC  LIMIT 1
        |";    
Если есть хоть один документ по контрагенту, то скорость их равно по 1 мсек, если документов нет, то Стандарт остается 1 мсек, а SQLite - 150 мсек (в 150 раз больше)
Получается Sqlite сканирует всю таблицу?
1 Sam1C
 
08.11.18
17:24
(0) Способ SQLite мне больше по душе,не нужен цикл по проверке вида документа (если тысяча документов другого вида будут позже, может потянуть больше времени), не обязательна графа отбора и т.п. Может у кого будут мысли, как максимально быстро получить последний документ определенного вида по Контрагенту?
2 v77
 
08.11.18
20:36
Да оно вроде и не должно быть быстрее. Через sqlite же теми же средствами 1с все работает. Да и сравнивать надо два запроса, а не запрос и простое чтение таблицы.
3 АгентБезопасной Нацио
 
08.11.18
20:46
(1) ну так и ищи по графе отбора, а не по шапке документа. Будет быстро. Если надо - пример завтра кину.
4 nicesc
 
08.11.18
20:49
Операция ORDER BY достаточно ресурсоемкая и здесь она не нужна.
Твой запрос не правильно отработает, если утренний документ сохранили в конец дня. Максимальный IDDOC будет у предыдущего документа.
Для того, что бы выдернуть последний документ тебе нужно обращаться к журналу документов.
5 АгентБезопасной Нацио
 
08.11.18
20:55
(4) упорядочивание необходимо, иначе это будет "возьми первый попавшийся".
Но выборку надо делать не по шапке и журналу, а по ссылкам документов (1scrdoc) - там есть для этого все нужные индексы
6 nicesc
 
08.11.18
21:08
(5) Если нужен один последний, то сортировать не нужна. Можно взять MAX(iddoc)
Через 1scrdoc не делал, попробую, спасибо за информацию. Через журнал можно сделать как то так:

ТекстЗапроса = "
  |SELECT
  |  MAX(Журнал.date||Журнал.time)
  |  ,Журнал.iddoc [Документ $Документ.Реализация]
  |FROM
  |  Журнал
  |INNER JOIN Документ_Реализация as докРеал
  | ON докРеал.iddoc = Журнал.iddoc
  |   and докРеал.Контрагент = :ВыбКонтрагент
  |WHERE
  |    iddocdef = :ВидДокумента.Реализация";
7 nicesc
 
08.11.18
21:15
похоже пора спать )
последнее условие избыточно, его можно выкинуть
8 nicxxx
 
08.11.18
22:05
(6)(4) В MSSQL запросы TOP(1) ID ORDER BY и MAX(ID) обычно сводятся к одному плану запроса - seek/scan+sort+stream aggregate+select top 1. Следствие - нет разницы, как писать исходный запрос.
(0) Надо date_time_iddoc из журнала документов использовать - сортировать по нему, как в (6) советуют. Метод Док.ВыбратьПоЗначению() наверное так и делает.
9 tesseract
 
08.11.18
23:15
А почему должно быть быстрее? Это просто простой перебор значений же. Если начать добавлять сложности всякие к запросу - будет заметен сильной прирост.

>>ORDER BY Док.IDDOC DESC  LIMIT 1

Ну так в любом случае будет Table Scan.  Хотя можно глянуть в плане запроса, но DESC - это в любом случае выборка во временное хранилище будет.
10 Sam1C
 
09.11.18
08:45
(9) Не факт, так как если есть хоть один документ отрабатывает за 1 мсек (как будто берет первый попавшийся), если нету 150 мсек. Хотя с другой стороны все равно, надо выбрать все данные для упорядочивания, а не первый попавшийся.Может IDDOC индексное поле по которому физически упорядочены данные в таблицы и идет чтение с конца таблицы и после первого попавшего значения выдает результат.
11 Sam1C
 
09.11.18
08:49
(4) наоборот правильно отработает, мне нужен последний по периоду, а не  по созданию. Документ можно создать задним числом и он не будет уже являться последним по контрагенту.
12 Sam1C
 
09.11.18
08:50
(11) + iddoc я так думаю при смене даты не меняется ж?
13 Sam1C
 
09.11.18
08:52
(3) Буду благодарен за пример!
14 Sserj
 
09.11.18
08:53
Да о чем вообще разговор.
1С-ный запрос знает про графу отбора, а в прямой запрос делается по таблице документа в которой контрагент не индексирован.
Прямой запрос нужно делать по таблице 1SCRDOC там индекс и на контраоента и на позицию документа есть.
15 Djelf
 
09.11.18
08:54
(10) Как раз факт.
order by desc не приводит к  временной таблице, т.к. движок умеет выбирать записи в обратном порядке по индексу и необходимости в дополнительной сортировки нет
но индекса по контрагенту тоже нет, поэтому по контрагенту идет чтение всей таблицы
но если контрагент есть то дальнейшие записи из-за limit 1 перебирать нет необходимости
вот и получается что когда контрагента нет, приходится перебирать все записи
16 АгентБезопасной Нацио
 
09.11.18
08:56
(14) нормальный прямой запрос тоже знает про графу отбора
17 Djelf
 
09.11.18
11:31
Вот как то так для 1sqlite

SELECT
    max(idx_MDID_PARENTVAL_CHILDDATE_CHILDTIME_CHILDID ) AS MAXDDATE
    ,Журнал.IDDOC [Документ :Документ.Реализация]
    ,Отбор.PARENTVAL [Контрагент :Неопределенный]
FROM __1S_CRDOC AS Отбор
LEFT JOIN Журнал ON Журнал.IDDOC=Отбор.CHILDID
WHERE Отбор.MDID=:ГрафаОтбора.Контрагент
    AND Отбор.PARENTVAL = Контрагент
    AND Журнал.IDDOCDEF=:ВидДокумента.Реализация


Контрагент должен быть id23
УстановитьПараметр(Контрагент,Контрагент,-1)

P.S. на оригинальной 1.0.2.6 и ниже может не сработать из за отсутствия оптимизации по max(). Не проверял. А на 1sqlite посвежее работает, брать тут: http://catalog.mista.ru/public/559826/
18 АгентБезопасной Нацио
 
09.11.18
11:33
(17) а не проще ему взять класс ПрямойЗапрос, и не париться?
19 Djelf
 
09.11.18
11:49
(18) Не проще. В ПрямомЗапросе нет отдельной оптимизации по получению последнего значения в таблице ссылок по графе отбора.
20 АгентБезопасной Нацио
 
09.11.18
11:58
там вообще оптимизаций мало. но хотя бы есть описание "по каким таблицам искать" и как.