Имя: Пароль:
1C
1С v8
Помогите оптимизировать запрос
0 Маленький Вопросик
 
04.11.18
13:23
ПоискДокументов.Текст = "ВЫБРАТЬ
                            |    РеализацияТоваровУслуг.Ссылка КАК Ссылка,
                            |    РеализацияТоваровУслуг.СуммаДокумента КАК СуммаДокумента,
                            |    РеализацияТоваровУслуг.Контрагент КАК Контрагент,
                            |    ВЫБОР
                            |        КОГДА НЕ СчетФактураВыданный.Ссылка.Проведен
                            |            ТОГДА СчетФактураВыданный.Ссылка = ЗНАЧЕНИЕ(Документ.СчетФактураВыданный.ПустаяСсылка)
                            |        ИНАЧЕ СчетФактураВыданный.Ссылка
                            |    КОНЕЦ КАК СФ
                            |ИЗ
                            |    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
                            |        ЛЕВОЕ СОЕДИНЕНИЕ Документ.СчетФактураВыданный КАК СчетФактураВыданный
                            |        ПО РеализацияТоваровУслуг.Ссылка = СчетФактураВыданный.ДокументОснование
                            |ГДЕ
                            |    РеализацияТоваровУслуг.Дата МЕЖДУ &Дата1 И &Дата2
                            |    И РеализацияТоваровУслуг.Организация = &Организация
                            |    И РеализацияТоваровУслуг.Проведен = ИСТИНА
                            |
                            |УПОРЯДОЧИТЬ ПО
                            |    РеализацияТоваровУслуг.Дата,
                            |    РеализацияТоваровУслуг.Номер";

смысл запроса понятен - выбираем все проведенные документы и связываем их с сф при условии, что сф проведена
1 rphosts
 
04.11.18
13:24
> И РеализацияТоваровУслуг.Проведен = ИСТИНА

Классика!
2 youalex
 
04.11.18
13:26
>СчетФактураВыданный.Ссылка.Проведен

лишняя точка(лишнее соединение)
3 rphosts
 
04.11.18
13:32
Нет никаких данных ни о размерах вашей базы ни о бизнес-процессах ни о количестве документов за обычно используемый для этого запроса период. Если у реализации и СФ одна и та-же дата, то скорее всего запрос прилично должен ускориться если предварительно отобрать во временную таблицу все проведенные СФ за искомый период и для искомой организации.
Ну а потом уже с ней соединять документы реализации.
Должно стать: быстрее и чтений данных на сервере будет меньше.
4 rphosts
 
04.11.18
13:32
(2) +1 - тоже классика
5 palsergeich
 
04.11.18
13:46
(1) оптимизатор это без ошибок ест.
(2) А это да не очень.
Тут еще неполное попадание в индекс будет в любом случае или скан кластеного индекса сразу или сик по одному индексу с нестед нупсом к кластерному
6 Маленький Вопросик
 
04.11.18
13:47
ПоискДокументов.Текст = "ВЫБРАТЬ
                            |    РеализацияТоваровУслуг.Ссылка КАК Ссылка,
                            |    РеализацияТоваровУслуг.СуммаДокумента КАК СуммаДокумента,
                            |    РеализацияТоваровУслуг.Контрагент КАК Контрагент,
                            |    ВЫБОР
                            |        КОГДА НЕ СчетФактураВыданный.Проведен
                            |            ТОГДА СчетФактураВыданный.Ссылка = ЗНАЧЕНИЕ(Документ.СчетФактураВыданный.ПустаяСсылка)
                            |        ИНАЧЕ СчетФактураВыданный.Ссылка
                            |    КОНЕЦ КАК СФ
                            |ИЗ
                            |    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
                            |        ЛЕВОЕ СОЕДИНЕНИЕ Документ.СчетФактураВыданный КАК СчетФактураВыданный
                            |        ПО РеализацияТоваровУслуг.Ссылка = СчетФактураВыданный.ДокументОснование
                            |ГДЕ
                            |    РеализацияТоваровУслуг.Дата МЕЖДУ &Дата1 И &Дата2
                            |    И РеализацияТоваровУслуг.Организация = &Организация
                            |    И РеализацияТоваровУслуг.Проведен
                            |
                            |УПОРЯДОЧИТЬ ПО
                            |    РеализацияТоваровУслуг.Дата,
                            |    РеализацияТоваровУслуг.Номер";
7 palsergeich
 
04.11.18
13:49
|УПОРЯДОЧИТЬ ПО
                            |    РеализацияТоваровУслуг.Дата,
                            |    РеализацияТоваровУслуг.Номер";
Уже только это приведет к скану кластеного индекса
8 Пузан
 
04.11.18
13:49
ТС зарегистрирован в 2009-ом году на Мисте. Чувак, я не знаю, может быть ты всегда консом работал до этого, или руководом, но как программист с таким опытом... Тебя надо гнать ссаными тряпками с должности прога.
9 Маленький Вопросик
 
04.11.18
13:49
(1) ну да. конструктор так собирает...

а по существу ничего не сказал...


не нужно временных таблиц.... в (6) запрос отбирает все реализации при условии, если ли у них сф(проведена) или ее вобще нет
10 Маленький Вопросик
 
04.11.18
13:50
(8) опиши ошибки явные
11 palsergeich
 
04.11.18
13:50
|УПОРЯДОЧИТЬ ПО
                            |    РеализацияТоваровУслуг.Дата,
                            |    РеализацияТоваровУслуг.Номер";

Вот явная
12 palsergeich
 
04.11.18
13:51
Если хочешь писать запросы которые работают реально быстро - всегда смотри сюда
https://its.1c.ru/db/metod8dev/content/1590/hdoc
13 Маленький Вопросик
 
04.11.18
13:52
(11) как надо?
14 palsergeich
 
04.11.18
13:58
Пакетный запрос.
В первом пакете соединения таблиц с условием по дате.
Скорее всего будет использоваться
[ОРРХ | ОРНР1 +] Дата + Ссылка вот этот индекс
Во втором внутренне соединение с таблицей документов и там уже вытаскиваем интересующий поля.
Но это быстрое решение, не факт что сразу зайдет
15 Маленький Вопросик
 
04.11.18
14:01
(14) ну напиши запрос то рабочий. спасибо за ответ
16 palsergeich
 
04.11.18
14:02
(15) 15000 вот прайс для примера http://www.gilev.ru/price/
17 palsergeich
 
04.11.18
14:03
См пункт Ускорение одного запроса
18 palsergeich
 
04.11.18
14:04
Сейчас суббота, мне нужно узнавать какая у тебя конфа что бы учесть все ньюансы, разворачивать, потом оптимизировать. И Вы хотите что бы я сделал это за спасибо?
За спасибо я указал ошибки и сделал Вам набросок
19 palsergeich
 
04.11.18
14:05
ОЙ календарь говорит что даже воскресение)
20 palsergeich
 
04.11.18
14:08
Может быть этот индекс [ОРРХ | ОРНР1 +] Реквизит + Дата + Ссылка будет задействовал, тогда всё еще проще.
Но я не готов тратить свое время на это сегодня
21 Маленький Вопросик
 
04.11.18
14:20
(4)

    ПоискДокументов.Текст = "ВЫБРАТЬ
                            |    РеализацияТоваровУслуг.Ссылка КАК Ссылка,
                            |    ВЫБОР
                            |        КОГДА НЕ СчетФактураВыданный.Проведен
                            |            ТОГДА СчетФактураВыданный.Ссылка = ЗНАЧЕНИЕ(Документ.СчетФактураВыданный.ПустаяСсылка)
                            |        ИНАЧЕ СчетФактураВыданный.Ссылка
                            |    КОНЕЦ КАК СФ
                            |ИЗ
                            |    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
                            |        ЛЕВОЕ СОЕДИНЕНИЕ Документ.СчетФактураВыданный КАК СчетФактураВыданный
                            |        ПО РеализацияТоваровУслуг.Ссылка = СчетФактураВыданный.ДокументОснование
                            |ГДЕ
                            |    РеализацияТоваровУслуг.Дата МЕЖДУ &Дата1 И &Дата2
                            |    И РеализацияТоваровУслуг.Организация = &Организация
                            |    И РеализацияТоваровУслуг.Проведен "+ВыборкаКт+"
                            |
                            |УПОРЯДОЧИТЬ ПО
                            |    РеализацияТоваровУслуг.Дата,
                            |    РеализацияТоваровУслуг.Номер";


сопоставил 10к реализаций 10к -  фактур (при условии, что она проведена) за 15 сек.

база файловая, ссд 850. коре й7-8700к
22 palsergeich
 
04.11.18
14:28
(21) Вы категорически игнорируете (14)
Ваше право
23 Cyberhawk
 
04.11.18
14:54
(1) А что тут не так?
24 palsergeich
 
04.11.18
15:03
(23) это свидетели c++, там за это по рукам бьют
26 palsergeich
 
04.11.18
15:12
(25) в (14) вполне себе подробно описано что делать. Одно дело он будет делать по направлению и я подскажу, другое дело значит него написать
27 rphosts
 
04.11.18
15:13
(5) вы слишком много от него хотите... по моему опыту менее 10% одинэснегов знает не то что как сервер СУБД соединяет таблицы, а что такое план выполнения запроса...
некоторые вообще смотрели как я фаром что-то в ТЖ искал как на наркоманскую магию.

(24) не совсем, но не красиво!
28 palsergeich
 
04.11.18
15:13
Хотя со стажем 9 лет то что я говорю не должно вызывать особых проблем для понимания
29 palsergeich
 
04.11.18
15:14
(27) в динамически типизируемом языке таки конструкции могут привести к ошибкам. Там например может при определенных условиях появится неопределенно.
30 palsergeich
 
04.11.18
15:17
Ну не в поле проведен, там никак, а вот в непредопредклееном поле булева типа - запросто, достаточно сделать тип составным
31 rphosts
 
04.11.18
15:19
(26) пусть для начала освоит временные таблицы. Если всё так как я думаю он может введением 1 ВТ резко уменьшить количество логических чтений.
Пусть хотя-бы с малого начнёт, а то  он сейчас на всё плюнет и через год-два снова с этими вопросами а ему: чувак да ты больше 10 лет на мисте и  бла-бла-бла
32 Маленький Вопросик
 
04.11.18
15:23
(31) хорошо, я сделаю через временную таблицу - туда выборку проведенных счетов фактур и соединю реализации - вт, посмотрим на сколько убыстрится
33 Cyberhawk
 
04.11.18
15:24
(24) "там за это по рукам бьют"
(27) "не совсем, но не красиво"
ЯННП, разъясните мне тупому, как красиво в запросе 1С надо делать?
34 rphosts
 
04.11.18
15:25
(32) разумеется нельзя тупо следовать рекомендациям... например 1с предписывала ВСЕГДА!!!! у ВТ делать по полям соединения индекс... на практике от этого в 90%+ запросов будет только вред (и по скорости выполнения и по нагрузке на сервер СУБД)
35 Маленький Вопросик
 
04.11.18
15:26
(33) никто не скажет похоже, тут бла-бла-бла.... никакой конкретики.... но про временную таблицу даже интересно)
36 Маленький Вопросик
 
04.11.18
15:27
(34) слушай, напиши как сделать провильное упорядочивание....
37 Cyberhawk
 
04.11.18
15:28
(35) Я про (1), а не про твой весь запрос
38 Маленький Вопросик
 
04.11.18
15:32
(34) ну можно плюнуть на все оптимизацию конечно - время работы запроса всего 15 сек - замерил... по 10к реализациям как я написал выше.

Ну раз пошла такая пляска, через ВТ конечно можно побаловаться...

Это не конкретная задача, просто субботняя разрядка для головы, я рассчитывал кто сделает получше :-)
39 palsergeich
 
04.11.18
15:32
(33) забей это субъективная хотелка.
40 Маленький Вопросик
 
04.11.18
15:35
(37) переделай запрос получше?
41 rphosts
 
04.11.18
15:36
(39) "Некрасивый самолёт не полетит." © Туполев А.
42 rphosts
 
04.11.18
15:37
(38) вот заюзай с ВТ - разомнёшь мозги... и да, сегодня уже не суббота
43 Cyberhawk
 
04.11.18
15:37
(41) Так что там некрасивого в (1)?
44 H A D G E H O G s
 
04.11.18
17:32
(0) Без временной таблицы будет ClusteredIndexScan
Правильно так
ВЫБРАТЬ
    РеализацияТоваровУслуг.Ссылка КАК Ссылка
ПОМЕСТИТЬ Реализации
ИЗ
    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
ГДЕ
    РеализацияТоваровУслуг.Дата МЕЖДУ &Дата1 И &Дата2
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Реализации.Ссылка КАК Реализация,
    ВЫБОР
        КОГДА НЕ СчетФактураВыданный.Проведен
            ТОГДА ЗНАЧЕНИЕ(Документ.СчетФактураВыданный.ПустаяСсылка)
        ИНАЧЕ СчетФактураВыданный.Ссылка
    КОНЕЦ КАК СчетФактура
ИЗ
    Реализации КАК Реализации
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.СчетФактураВыданный КАК СчетФактураВыданный
        ПО Реализации.Ссылка = СчетФактураВыданный.ДокументОснование
ГДЕ
    Реализации.Ссылка.Организация = &Организация
    И Реализации.Ссылка.Проведен = ИСТИНА

УПОРЯДОЧИТЬ ПО
    Реализации.Ссылка.Дата,
    Реализации.Ссылка.Номер
45 H A D G E H O G s
 
04.11.18
17:36
Не знаю, че так оптимизатор SQL лажает.

Если одним запросом - выборка 50 тыс реализаций из 1.1 млн длиться 9.6 секунд на непрогретом HDD 5400, упираясь в диск.

Если запросом с пакетом - выборка 7.3 тыс реализаций из 107 тыс длиться 0.5+0.4 секунды на непрогретом HDD 5400, упираясь в диск.
46 H A D G E H O G s
 
04.11.18
17:36
выбирал из 2-х разных баз, было лень перезапускать.
47 rphosts
 
04.11.18
17:37
(44) по СФ наверняка тот-же период, поэтому разве не  отобрать проведённые СФ в ВТ?
48 H A D G E H O G s
 
04.11.18
17:39
(47) Ну этого в условии задачи нет.
49 rphosts
 
04.11.18
17:41
(48) я чела спрашивал... молчит, зараза. В моей артели это правило (с точностью до дня) не нарушается
50 Маленький Вопросик
 
04.11.18
18:11
(49) чет не приросло быстродействие, все теже 15 сек

ПоискСФ                         = Новый Запрос();
    МенеджерСФ                         = Новый МенеджерВременныхТаблиц;
    
    ПоискСФ.МенеджерВременныхТаблиц = МенеджерСФ;
    
    ПоискСФ.Текст     = "ВЫБРАТЬ
                      |    СчетФактураВыданный.Ссылка КАК СФ,
                      |    СчетФактураВыданный.ДокументОснование КАК ДокОснование
                      |ПОМЕСТИТЬ ВТ_СчетФактуры
                      |ИЗ
                      |    Документ.СчетФактураВыданный КАК СчетФактураВыданный
                      |ГДЕ
                      |    СчетФактураВыданный.Проведен
                      |    И СчетФактураВыданный.Дата МЕЖДУ &Дата1 И &Дата2
                      |    И СчетФактураВыданный.Организация = &Организация";
    
    ПоискСФ.УстановитьПараметр("Дата1",         НачПериода);
    ПоискСФ.УстановитьПараметр("Дата2",         КонПериода);
    ПоискСФ.УстановитьПараметр("Организация",     ЭтаФорма.Огранизация);
    
    ПоискСФ.Выполнить();
    
    ПоискДокументов.МенеджерВременныхТаблиц = МенеджерСФ;    
    
    
    ПоискДокументов.Текст   = "ВЫБРАТЬ
                              |    РеализацияТоваровУслуг.Ссылка КАК Ссылка,
                              |    ВТ_СчетФактуры.СФ КАК СФ
                              |ИЗ
                              |    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
                              |        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_СчетФактуры КАК ВТ_СчетФактуры
                              |        ПО РеализацияТоваровУслуг.Ссылка = ВТ_СчетФактуры.ДокОснование
                              |ГДЕ
                              |    РеализацияТоваровУслуг.Проведен
                              |    И РеализацияТоваровУслуг.Дата МЕЖДУ &Дата1 И &Дата2
                              |    И РеализацияТоваровУслуг.Организация = &Организация "+ВыборкаКт+"
                              |
                              |УПОРЯДОЧИТЬ ПО
                              |    РеализацияТоваровУслуг.Дата,
                              |    РеализацияТоваровУслуг.Номер";
51 H A D G E H O G s
 
04.11.18
18:13
(50) попробуй реиндексировать и мой запрос.
Ну, может еще и то, что файловая.
52 Маленький Вопросик
 
04.11.18
18:13
(44) слушай, а если у тебя у документа нет СФ... сплошь и рядом, поэтому основная таблица - все-таки реализации
53 Маленький Вопросик
 
04.11.18
18:15
(51) 9 сек... хорошо! аааа... я же выводил результат в табличную часть... щас без вывода проверю.
54 H A D G E H O G s
 
04.11.18
18:16
(52) У меня и так основная таблица - реализация.
55 H A D G E H O G s
 
04.11.18
18:19
(52) Проблема в том, что отбор идет по дате РТУ - значит в отборе кластерный индекс не участвует. Участвует некластерный индекс, но в нем нет реквизитов (Проведен, Организация) - поэтому, по хорошему, должен быть поиск по некластерному индексу и переход к странице данных по PID (indexseek+keylookup). Но глупый оптимизатор решает, что выгоднее тупо просканить кластерный индекс и лажает на 9 секунд.
56 palsergeich
 
04.11.18
18:19
В первом пакете организацию убери
57 Маленький Вопросик
 
04.11.18
18:20
(54) да-да, увидел

Реализации КАК Реализации
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.СчетФактураВыданный


короче у меня получилось так

НашлиДоки = ПоискДокументов.Выполнить().Выгрузить();    
    
    ВВВ = ТекущаяДата();    
    БББ = ВВВ - АА;
    Сообщить(ВВВ);
    Сообщить(БББ);
    
    Сообщить(НашлиДоки.Количество()); //10254

работа запроса - 0 сек на выборке 10254 док


это конечно на ссд и й7 как я писал выше
58 palsergeich
 
04.11.18
18:20
И в первом пакете выбирай только ссылки. Во втором пакете внутреннее соединение с реальными таблицами там и вытащишь что надо
59 Маленький Вопросик
 
04.11.18
18:20
это вывод в табличную часть занял 15 сек )))))) сорри....
60 palsergeich
 
04.11.18
18:22
(57) в файловой базе записи в реальных таблицах не упорядочиваются так как в серверных базах. V8unpack очень хорошо это показывает
61 Маленький Вопросик
 
04.11.18
18:23
ладно, всем спасибо!
62 palsergeich
 
04.11.18
18:23
По этому чем более полно на больших выборках попадаешь в индекс тем лучше результат.
63 H A D G E H O G s
 
04.11.18
18:28
На самом деле, еще оптимальнее так

ВЫБРАТЬ
    РеализацияТоваровУслуг.Ссылка КАК Ссылка
ПОМЕСТИТЬ Реализации
ИЗ
    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
ГДЕ
    РеализацияТоваровУслуг.Дата МЕЖДУ &Дата1 И &Дата2
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    СчетФактураВыданный.Ссылка КАК Ссылка
ПОМЕСТИТЬ СчетФактуры
ИЗ
    Документ.СчетФактураВыданный КАК СчетФактураВыданный
ГДЕ
    СчетФактураВыданный.Дата МЕЖДУ &Дата1 И &Дата2
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Реализации.Ссылка КАК Реализация,
    ВЫБОР
        КОГДА НЕ СчетФактуры.Ссылка.Проведен
            ТОГДА ЗНАЧЕНИЕ(Документ.СчетФактураВыданный.ПустаяСсылка)
        ИНАЧЕ СчетФактуры.Ссылка
    КОНЕЦ КАК СчетФактура
ИЗ
    Реализации КАК Реализации
        ЛЕВОЕ СОЕДИНЕНИЕ СчетФактуры КАК СчетФактуры
        ПО (Реализации.Ссылка = СчетФактуры.Ссылка.ДокументОснование)
ГДЕ
    Реализации.Ссылка.Организация = &Организация
    И Реализации.Ссылка.Проведен = ИСТИНА

УПОРЯДОЧИТЬ ПО
    Реализации.Ссылка.Дата,
    Реализации.Ссылка.Номер
64 palsergeich
 
04.11.18
18:30
(63) со 2 запросом в пакете не соглашусь ибо счёт фактура может быть другой датой ,нежели реализация, их надо соединить в одном пакете используя индекс дата ссылка для реализации и кластерный для СФ. И будет ок
65 palsergeich
 
04.11.18
18:31
Именно такой запрос я имел ввиду в (14)
66 H A D G E H O G s
 
04.11.18
18:33
(64) Да какая разница, как ни крути, все равно индекс по ДокументОснование у счет-фактуры использоваться не будет.
67 H A D G E H O G s
 
04.11.18
18:33
Вот просто очешуительная картинка, как по разному работает SQL для 2 одинаковых случаев.

https://yadi.sk/i/jZPg2hUp3Mxj3Q
68 H A D G E H O G s
 
04.11.18
18:35
Причем счет-фактур (99тыс) почти столько же, сколько и РТУ (102 тыс).
69 palsergeich
 
04.11.18
18:36
(67) странно а по какой таблице лупсы идут?
70 H A D G E H O G s
 
04.11.18
18:37
doc469 - сф
doc456 - рту.

размер выборки - 6861 (ну там видно).
71 H A D G E H O G s
 
04.11.18
18:37
(69) Лупсы - по РТУ, merge - по СФ.
72 H A D G E H O G s
 
04.11.18
18:40
На самом, на самом, на самом на деле, лупсы то лучше :-)
73 palsergeich
 
04.11.18
18:41
Ну мб
74 H A D G E H O G s
 
04.11.18
18:42
При времени выполнения всего запроса в 52 мс. Лупсы выполнили 7338 чтений (1 запись 7338раз). Мерги - 99000 чтений (99000 записей 1 раз).

Все хорошо, пока у нас горячий кэш.
75 H A D G E H O G s
 
04.11.18
18:44
Лупсы предсказуемей - им ничего не надо для выполнения.
Мерги требуют сортировки - все идет хорошо, пока данных не станет долго и ты не напоришься на tablespool
76 H A D G E H O G s
 
04.11.18
18:47
Однако, спасибо тебе автор, ты мне прям еще одну темную сущность SQL-я открыл. Буду очень внимателен к большим отборам по некластерным индексам.
77 H A D G E H O G s
 
04.11.18
18:48
"к большим отборам" -> "к относительно большим отборам"
78 palsergeich
 
04.11.18
18:48
Это я знаю, просто я уже немножечко праздник поотмечал)
Ну хорошо, запрос прокачанный)
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший