Имя: Пароль:
1C
1С v8
Знатокам запросов. Как реализовать сие?
0 Ksandr
 
03.08.12
15:38
Коллеги, доброй Вам пятницы!

Ситуация следующая:
Есть документ1 с реквизитом Период, например 1 квартал
Есть документ2 в количестве 3 штуки с реквизитом Период со значениями месяцев (первый за январь, второй за февраль, третий за март).

Так вот в запросе необходимо однозначно определить соответствие документа1 документу2 по периоду.

Как это сделал я первый раз:

Документ1.Период = Документ2.Период
ИЛИ Документ1.Период.ДатаНачала <= Документ2.Период.ДатаНачала
И Документ1.Период.ДатаОкончания >= Документ2.Период.ДатаОкончания

Получил на выходе время выполнения запроса 1.2 секунды. Много.
Полез в профайлер, помедитировал. Попробовал убрать от ИЛИ и далее.
Получил время выполнения 0.2 секунды.

Но результат заведомо неверен.

Далее убрал первую строку и оставил сравнение только по реквизитам, т.к. 1С рекомендует избегать конструкции ИЛИ в условии в запросе.

Получил время выполнения 0.7 секунды

Профайлер намекает на
- NESTED LOOP
- - NESTED LOOP
при таком раскладе

Документ1.Период.ДатаНачала <= Документ2.Период.ДатаНачала
И Документ1.Период.ДатаОкончания >= Документ2.Период.ДатаОкончания

вопрос собственно в производительности. Каким образом получить нужный результат за минимальное время.
1 Ненавижу 1С
 
гуру
03.08.12
15:40
сначала скажи, как это "соответствие" должно работать?
2 DexterMorgan
 
03.08.12
15:41
Документ1.Период.ДатаНачала = НАЧАЛОПЕРИОДА(Документ2.Период.ДатаНачала, КВАРТАЛ)?
3 Ksandr
 
03.08.12
15:45
(1) Период либо равен, либо вложен
(2) не всегда это квартал, может быть год и кварталы, месяц и недели
4 H A D G E H O G s
 
03.08.12
15:46
Период  - это что за тип?
5 Ненавижу 1С
 
гуру
03.08.12
15:47
(3) значит просто вложен, потому что равен все равно вложен
6 Ненавижу 1С
 
гуру
03.08.12
15:48
(4) подозреваю справочник ))
7 Ненавижу 1С
 
гуру
03.08.12
15:49
Документ2.Период.ДатаНачала МЕЖДУ Документ2.Период.ДатаНачала И Документ2.Период.ДатаОкончания
И
Документ2.Период.ДатаОкончания МЕЖДУ Документ2.Период.ДатаНачала И Документ2.Период.ДатаОкончания
8 Buster007
 
03.08.12
15:50
а я так подозреваю время выполнения такое не из-за того, что применяется "или", а вовсе из-за того, что через точку меньше надо писать.
9 Ksandr
 
03.08.12
15:52
(7) прирост 0.04 секунды :)
10 Ksandr
 
03.08.12
15:53
(6) ага
Справочник Периоды
Реквизиты Периодичность - перечилсение
ДатаНачала - Дата
ДатаОкончания - Дата
11 mrParadox
 
03.08.12
15:54
//Получил время выполнения 0.7 секунды

норм время
12 Ненавижу 1С
 
гуру
03.08.12
15:56
(10) индексы на ДатаНачала и ДатаОкончания сделай
13 Ksandr
 
03.08.12
15:56
Есть предположение, что поможет здесь только при создании документ2 (тот что с вложенным периодом) писать в реквизит отдельный реквизит вычисленный период, чтобы при получении данных запросом проверять только на равенство
14 Ksandr
 
03.08.12
15:57
(12) Уже в наличии
15 KAO111
 
03.08.12
16:09
(13) вместо записи в отдельный реквизит можно попробовать получить временную таблицу отдельным пакетом
16 KAO111
 
03.08.12
16:10
сколько времени уйдет получить документы по отбору с выводом дат
17 Ksandr
 
03.08.12
16:54
(15) тут динамический список. подзапрос еще медленнее работать будет
18 МихаилМ
 
03.08.12
17:04
19 МихаилМ
 
03.08.12
17:06
(12) будет только хуже
20 Ksandr
 
03.08.12
17:08
(19) Можно в двух словах - почему?
21 МихаилМ
 
03.08.12
17:10
(20)

потому что ms sql не сможет выбрать какой из индексов ДатаНачала или ДатаОкончания
использовать и применит fullscan
22 Ksandr
 
03.08.12
17:12
(21) СУБД Oracle,
в плане ни одного table scan нет,
а чем index full scan плох?
23 H A D G E H O G s
 
03.08.12
17:13
(22) Ничем не плох. Не слушай товарища.
24 H A D G E H O G s
 
03.08.12
17:13
Особенно в свете (18)
25 hhhh
 
03.08.12
17:18
(22) ну вынесите ДатаНачала и ДатаОкончания в Документ. Тогда точно раз в 10 быстрее будет
26 МихаилМ
 
03.08.12
17:19
(22)

плох большой ресурсоёмкостью.

для небольших таблиц и индексов (до 3000 записей) -

не критично.
27 milan
 
03.08.12
17:20
(0) Запили толком справочник с периодами, в документе 2 реквизит с типом период и отбирай по иерархии, а лучше по равенству, тогда забегает
28 H A D G E H O G s
 
03.08.12
17:25
(26) Че там? Построить индексы с учетом еще 8 байт?
29 H A D G E H O G s
 
03.08.12
17:25
Может пакетным сначало отобрать Периоды верные, а потом уж 2 запросом - документы.
30 МихаилМ
 
03.08.12
17:29
+26
плохи  ростом времени исполнения пропорционально колву записей
даже на совремнных компьютерах полное сканирование таблиц (индексов) с более 100 000 запсей

крайне не желательно.
31 H A D G E H O G s
 
03.08.12
17:31
(30) Вы счаст про что говорите?
32 milan
 
03.08.12
17:31
(29) да с реквизитами балалайка, надо 1 раз посчитать чего за период и записать либо в реквизит, либо в РС, тогда ускорится
33 МихаилМ
 
03.08.12
17:32
(31)
про плохость фулсканов
34 H A D G E H O G s
 
03.08.12
17:35
(33) Речь про tablescan или indexscan

говорите четче.
35 mih_io
 
03.08.12
17:35
(0)Я бы на вашем месте тогда перед тем, как формировать этот отчет, прогнал бы по справочнику типа "Период" и посмотрел вхождение всех элементов типа "период" которые могут быть за тот элемент период, что указан в документе1.

И потом сделал отбор всех документов2 у которых реквизит период входит в это подмножество.
36 milan
 
03.08.12
17:41
(32),(35) правильный ответ в (13), так вся 1С и работает - есть документы, они что-то вычисляют и пишут в регистры, а оттуда легко и быстро достать.
OLAP+OLTP=СИЛА
37 Serginio1
 
03.08.12
17:41
Наверное проще получить левое соединение по справочнику периоды
Документ1.Период.ДатаНачала <= Периоды.ДатаНачала
И Документ1.Период.ДатаОкончания >= Периоды.ДатаОкончания
С селектом Период.Ссылка как ПериодСсылка
А затем уже получить соединение с условием
Документ1.ПериодСсылка = Документ2.Период
38 mih_io
 
03.08.12
17:47
(36) а если есть период квартал, период месяц и период неделя? то когда создается документ2, то дополнительный период какой делать?

Ведь мы можем запросить и за квартал и за месяц и за год.

Как по мне нафик не нужен второй реквизит. Создать подмножество периодов входящих в заданный перед формированием основного запроса, будет моментальное дело и гибкое.

Нет, если у нас только кварталы и месяца, то можно и дополнительный реквизит сделать. чё же. Сэкономим на времени создания этого подмножества )
39 milan
 
03.08.12
17:50
(38) нужно отойти от отбора по датам и плавно перейти к отбору по реквизиту период. Имха 1.2 секунды это не просто медленно, это катастрофически медленно, а уж в динамическом списке еще и СКЛ сервер нагнется, если много народу такие списки пооткрывают ;)
40 milan
 
03.08.12
17:51
(38) неделя в иерархии квартал, там 3 джоина по справочнику из 100 элементов
41 mih_io
 
03.08.12
18:01
(39) Уважаемый, я что, как то неясно объяснил? Я и предлагаю отбор по элементам справочника типа "Период".

Пример. есть 4 элемента справочника "Период" с реквизитами:

Наименование: "Квартал 1 2012"
ДанаНач: 01.01.2012
ДатаКон: 31.03.2012

Наименование: "январь 2012"
ДанаНач: 01.01.2012
ДатаКон: 31.01.2012

Наименование: "Февраль 2012"
ДанаНач: 01.02.2012
ДатаКон: 29.02.2012

Наименование: "Март 2012"
ДанаНач: 01.03.2012
ДатаКон: 31.01.2012

Внимание вопрос, когда мы делаем отбор за квартал, как долго и сложно нам определить, что в этот квартал входят 3 элемента типа период с наименованием "январь 2012", "Февраль 2012", "Март 2012" и потом уже документ2 отобрать где реквизит период входит в это подмножество? И вопрос два, зачем в такой схеме дополнительный реквизит? особенно когда уровней периода может больше чем один, не только квартал-месяц.
42 milan
 
03.08.12
18:04
(41) дак я только "за", только автор сам нашел решение в (13), наверное уже реализовал и поделится впечатлениями
43 Ksandr
 
03.08.12
18:16
(42) Пока не реализовал. Курю планы запросов во всю.
44 milan
 
03.08.12
18:19
(43) бросай курить, уж больно охота посмотреть чего получится ;) всяко быстрее первоначального варианта, хоть кури хоть не кури.
45 Ksandr
 
07.08.12
20:12
В общем, индексы по ДатаНачала и ДатаОкончания убрал, т.к. во-первых табличка не большая, а во-вторых все равно NESTED LOOPS в плане, а не INDEX SCAN.

Реквизиты добавлять не стал, т.к. их заполнение еще реализовать придется, а это трудоемко (в данном конкретном случае). Возился с соединениями, в итоге узким и ресурсоемким местом в запросе стало МАКСИМУМ(..) СГРУППИРОВАТЬ ПО ...
но с этим уже ничего не поделаешь.

10 чел. на стенде разработки, полет нормальный. среднее время выполнения запроса 0.3 сек

+100 очков опыта :)
46 Ksandr
 
07.08.12
20:16
быстродействие отнимало еще соединение с индексированным полем содержащим неуникальные значения, поправил.
47 H A D G E H O G s
 
07.08.12
20:56
Пробовал ВТ?
48 Ksandr
 
07.08.12
22:26
(47) Я бы с радостью, но это динамический список
49 H A D G E H O G s
 
07.08.12
22:38
(48) Самое смешное, что можно, да не до конца :-)
От руки пиши.
50 mistеr
 
07.08.12
23:44
(45) Покажи план от (7) и твой окончательный, если не сложно.
51 Ksandr
 
08.08.12
00:52
(50) Сейчас уже сложно, если не забуду, в четверг выложу.
52 Ksandr
 
08.08.12
00:52
(49) Спасибо, попробую потестить.
53 Ksandr
 
09.08.12
17:49
Яху! Скорость выполнения запроса теперь составляет 0.058 секунды!
Спасибо (49)

План запроса:
https://dl.dropbox.com/u/39913355/Oracle%20Enterprise%20Manager%20(SYSTEM)%20-%20SQL%20Details-%20gt4rt885zrzvn.png

Что мы имеем, если раньше Cost измерялась в тысячах и миллионах то теперь десятки!
54 Ksandr
 
09.08.12
17:49
55 H A D G E H O G s
 
09.08.12
17:51
(53) Покажи текст 1С запроса плтз.
56 H A D G E H O G s
 
09.08.12
17:51
плиз
57 Ksandr
 
09.08.12
18:13
(56) Кинул в почту
58 acsent
 
09.08.12
18:20
нужно сначала составить таблицу соответствий периодов, а потом соединять документы через эту таблицу, при этом проиндексировав поле период, если только по периоду будет соединение
59 Ksandr
 
09.08.12
18:33
Кстати, с индексами ВТ еще не возился, теперь поле для оптимизации стало еще больше.
Интересно до 0.03 или 0.01 доведу? ))
60 Ksandr
 
09.08.12
19:25
ВТ с условиями + {ГДЕ ...} + Индексы = +25% к производительности.
61 Ksandr
 
09.08.12
19:25
Продолжаю наблюдения. Уже из спортивного интереса.
62 Ksandr
 
09.08.12
19:29
(58) Воспользовался советом, спасибо!
63 H A D G E H O G s
 
09.08.12
19:30
Посмотрел запрос -
ЗАПРОСССС, Здоровеннный ЗАПРОС...

Что за конфа?
64 Ksandr
 
09.08.12
20:18
(63) Консолидация
65 mistеr
 
10.08.12
03:13
(54) Ну и наворачивает 1Ска...
(60) Советую остановиться. Лучше потратить время на что-нибудь полезное; а еще +10% пользователи не оценят.
Да, и на Cost не смотри, это условные попугаи.