Имя: Пароль:
1C
1С v8
Подскажите, как лучше оптимизировать запрос
,
0 Иоган
 
19.05.16
16:44
Подскажите пожалуйста, как лучше оптимизировать запрос:

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

СГРУППИРОВАТЬ ПО
    РеализацияТоваровУслугТовары.Номенклатура
58 GenAcid
 
20.05.16
10:12
(55) этот "индексы в конкретных случаях могут замедлять неожиданно"?

Так в каких конкретных случаях индексы могут неожиданно замедлить выборку?
59 AneJIbcuH
 
20.05.16
10:13
(56) 0-O ты где узнал, что внутренее соединение ухуджает производительность? Просто логически поразмыслил?
60 ViSo76
 
20.05.16
10:14
(57) Лишняя проверка - нагрузка на ПЦ, она избыточна. Нужно смотреть план исполнения но скорее всего в начале данные отберутся, а затем уже будут делаться агрегаты но я в этом не уверен на 100%, а по этому лучше внутреннее, чтобы память меньше расходовать.
61 ViSo76
 
20.05.16
10:15
(59) Ну там тупо есть проверка дополнительная при соединении, возможно что это микросекунды, но всё же...
62 ViSo76
 
20.05.16
10:16
(61) Я говорю это по конкретный случай, про то что ТЧ есть всегда, а то начнёте тут развозить...
63 Лохматые Уши
 
20.05.16
10:17
(60) Да вот не лишняя она. Вот ты упертый товарищ.
64 ViSo76
 
20.05.16
10:18
(63) В левом соединении не лишняя, но я уже отписался нет ТЧ ставить левое. Это вы упёртые читать нужно что пишут.
65 ViSo76
 
20.05.16
10:20
(64) но я уже отписался нет ТЧ ставить внутреннее ( описался )
66 AneJIbcuH
 
20.05.16
10:24
(65) Ты сдавал спеца по платформе или требования хоть раз смотрел?
67 ViSo76
 
20.05.16
10:26
(66) спеца не смотрел, требования чего?
68 AneJIbcuH
 
20.05.16
10:27
Напоминаешь только только окрылившегося Программиста 1С, при этом только в своей голове.
69 ViSo76
 
20.05.16
10:29
(68) По моему совету (12), кроме внутреннего ещё есть претензии? Или все тут об астракциях думают, а не конкретный случай рассматривают? Если претензий нет, то кругом, раз, два
70 AneJIbcuH
 
20.05.16
10:30
(67) МатЧасти (как говоришь) нахватался вроде, а как использовать не знаешь.
71 ViSo76
 
20.05.16
10:37
(70) Ну давай, жги, только не в лужу, а обоснованно, с примерами. Запрос (12) я накатал лёжа на диване в блокноте почти копипастом, про внутренне в тот момент не думал, так как в текущий момент в самописке ТЧ всегда заполнена. Ты давай умудренный знаниями покажи моменты где я не прав. Внутреннее мы уже обсудили, что ещё? Меня интересует утверждение "а как использовать не знаешь"
72 Kolyasik
 
20.05.16
10:39
(61) план запроса смотрел?
73 AneJIbcuH
 
20.05.16
10:39
(71) Всё просто, чем твой запрос отличается таким особенным от (0) ?
74 ViSo76
 
20.05.16
10:42
(73) С тобой всё понятно. Ну тогда напиши в какой запрос будет переведён (0) для SQL и тогда всё поймёшь.
75 AneJIbcuH
 
20.05.16
10:56
(74) По твоему отличный прирост в производительности мы увидим? Тебе когда необходимо получить реквизит какого-либо ещё реквизита, тоже запрос пишешь?
76 ViSo76
 
20.05.16
10:57
(75) Смотря что, могу и через точку, если гарантированно SQL точкой не будет испорчен
77 Kolyasik
 
20.05.16
11:00
ЛЕВОЕ
78 Kolyasik
 
20.05.16
11:00
'SELECT
T2._Fld28317RRef,
CAST(SUM(T2._Fld28322) AS NUMERIC(26, 8))
FROM dbo._Document862 T1
LEFT OUTER JOIN dbo._Document862_VT28315 T2
ON (T1._IDRRef = T2._Document862_IDRRef) AND T2._Fld1704 = T1._Fld1704
WHERE ((T1._Fld1704 = P1)) AND (T1._Posted = 0x01 AND ((T1._Date_Time >= @P2) AND (T1._Date_Time <= @P3)))
GROUP BY T2._Fld28317RRef',N'P1 numeric(10),@P2 datetime2(3),@P3 datetime2(3)',0,'4015-04-01 00:00:00','4015-04-30 23:59:59'
79 Kolyasik
 
20.05.16
11:01
ВНУТРЕННЕЕ
'SELECT
T2._Fld28317RRef,
CAST(SUM(T2._Fld28322) AS NUMERIC(26, 8))
FROM dbo._Document862 T1
INNER JOIN dbo._Document862_VT28315 T2
ON (T1._IDRRef = T2._Document862_IDRRef) AND T2._Fld1704 = T1._Fld1704
WHERE ((T1._Fld1704 = P1)) AND (T1._Posted = 0x01 AND ((T1._Date_Time >= @P2) AND (T1._Date_Time <= @P3)))
GROUP BY T2._Fld28317RRef',N'P1 numeric(10),@P2 datetime2(3),@P3 datetime2(3)',0,'4015-04-01 00:00:00','4015-04-30 23:59:59'
80 Kolyasik
 
20.05.16
11:02
(0)
'SELECT
T1._Fld28317RRef,
CAST(SUM(T1._Fld28322) AS NUMERIC(26, 8))
FROM dbo._Document862_VT28315 T1
LEFT OUTER JOIN dbo._Document862 T2
ON (T1._Document862_IDRRef = T2._IDRRef) AND (T2._Fld1704 = P1)
WHERE ((T1._Fld1704 = @P2)) AND (T2._Posted = 0x01 AND ((T2._Date_Time >= @P3) AND (T2._Date_Time <= @P4)))
GROUP BY T1._Fld28317RRef',N'P1 numeric(10),@P2 numeric(10),@P3 datetime2(3),@P4 datetime2(3)',0,0,'4015-04-01 00:00:00','4015-04-30 23:59:59'
81 AneJIbcuH
 
20.05.16
11:06
(80) Благодарствую! Некогда было подобное выкатить.
82 ViSo76
 
20.05.16
11:06
(80) Всё правильно. (73) Почувствуй разницу. Теперь объясни что будет делать база данных на запросе (79) и (80)
83 Simod
 
20.05.16
11:12
Никого не смущает, что в (0) суммируется количество в разных ед.измерения?
84 AneJIbcuH
 
20.05.16
11:17
(82) Тесты, тесты со временем давай. Не очевидно, что SQL плохо в любом случае отработает.
85 GenAcid
 
20.05.16
11:17
(82) Я тебе точно говорю что то, что будет делать SQL, зависит от того, как ее оптимизатор обработает эти запросы. В 99% случаев они будут обрабатываться идентично.
86 ViSo76
 
20.05.16
11:24
(84) Тесты к (80) с благодарностью
87 ViSo76
 
20.05.16
11:50
(85) Соглашусь, что если оптимизатор отработает хорошо, то да, а если это файловая база? Я предпочитаю не полагаться на оптимизатор.
88 Kolyasik
 
20.05.16
12:09
(86) при левом соединении будет null что ошибка, в (0) не оптимально
89 Kolyasik
 
20.05.16
12:11
план запроса в (0)
StmtText                                                                                                                                                                                                                                                                                                                                                                                                                  
--------                                                                                                                                                                                                                                                                                                                                                                                                                  
Compute Scalar(DEFINE:([Expr1005]=CONVERT(numeric(26,8),[Expr1004],0)))                                                                                                                                                                                                                                                                                                                                                    
  |--Parallelism(Gather Streams)                                                                                                                                                                                                                                                                                                                                                                                          
       |--Stream Aggregate(GROUP BY:([T1].[_Fld28317RRef]) DEFINE:([Expr1004]=SUM([partialagg1006])))                                                                                                                                                                                                                                                                                                                      
            |--Sort(ORDER BY:([T1].[_Fld28317RRef] ASC))                                                                                                                                                                                                                                                                                                                                                                  
                 |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([T1].[_Fld28317RRef]))                                                                                                                                                                                                                                                                                                          
                      |--Hash Match(Partial Aggregate, HASH:([T1].[_Fld28317RRef]), RESIDUAL:([pepsico_erp].[dbo].[_Document862_VT28315].[_Fld28317RRef] as [T1].[_Fld28317RRef] = [pepsico_erp].[dbo].[_Document862_VT28315].[_Fld28317RRef] as [T1].[_Fld28317RRef]) DEFINE:([partialagg1006]=SUM([pepsico_erp].[dbo].[_Document862_VT28315].[_Fld28322] as [T1].[_Fld28322])))                                          
                           |--Nested Loops(Inner Join, OUTER REFERENCES:([T2].[_IDRRef], [Expr1007]) WITH UNORDERED PREFETCH)                                                                                                                                                                                                                                                                                              
                                |--Clustered Index Seek(OBJECT:([pepsico_erp].[dbo].[_Document862].[_Document862HPK] AS [T2]), SEEK:([T2].[_Fld1704]=[@P1]),  WHERE:([pepsico_erp].[dbo].[_Document862].[_Date_Time] as [T2].[_Date_Time]>=[@P3] AND [pepsico_erp].[dbo].[_Document862].[_Date_Time] as [T2].[_Date_Time]<=[@P4] AND [pepsico_erp].[dbo].[_Document862].[_Posted] as [T2].[_Posted]=0x01) ORDERED FORWARD)
                                |--Clustered Index Seek(OBJECT:([pepsico_erp].[dbo].[_Document862_VT28315].[_Documen862_VT28315_IntKeyInd] AS [T1]), SEEK:([T1].[_Fld1704]=[@P2] AND [T1].[_Document862_IDRRef]=[pepsico_erp].[dbo].[_Document862].[_IDRRef] as [T2].[_IDRRef]) ORDERED FORWARD)
90 Kolyasik
 
20.05.16
12:12
+(89) фиговенько вставляется )
91 Тролль главный
 
20.05.16
12:18
а в чем смысл СУММА(РеализацияТоваровУслугТовары.Количество)
зачем суммировать количество различной номенклатуры?
92 ViSo76
 
20.05.16
12:22
(91) Почему разной? Группировку по номенклатуре ещё никто не отменял
93 ViSo76
 
20.05.16
12:26
(89) Спасибо, можешь привести план запроса (79). Мне интересно ГДЕ ( все пункты ) накладывается до соединения сокрее всего. И в начале будет отбор по индексу Дата ( диапазон ), а далее наложены другие фильтра, и только в последнем моменте внутренее...
94 xxTANATORxx
 
20.05.16
12:38
вы чё спорите?
в (8) правильный ответ
95 ViSo76
 
20.05.16
12:46
(94) Нафига делать отдельный индекс, которые будет ухудшать INSERT, если можно и так построить достаточно быстро работающий запрос? Почитай по OLTP где DBA прежде чем добавить индекс собирают информацию о там как это отразится на других частях системы, а тут давайте по каждому чиху индексов насоздадим... некошерно это.
96 bolobol
 
20.05.16
12:47
(0) Усилить сервер ещё не предлагали? А то выборка по одной таблице медленно работает...
97 bolobol
 
20.05.16
12:49
(0) Вариант 2. Подготавливать данные в отдельный регистр. Обновлять механизмом регистрации изменений.
98 ViSo76
 
20.05.16
12:52
(97) Уже даже не смешно. Из-за неправильно написанного запроса пытаются годзилу тут сваять...
99 bolobol
 
20.05.16
12:54
(98) проясните, пожалуйста, несведущему в планах, что в (89) не так напланировано, по вашему. Спасибо!
100 Kolyasik
 
20.05.16
12:56
(99) план одинаков практически у всех запросов
101 Kolyasik
 
20.05.16
12:57
+ (100) я не сказал что он не правильный
102 bolobol
 
20.05.16
12:57
(100) Кагбэ, это ожидаемо. Все приведённые запросы - одни и те же... из штанов.
103 Kolyasik
 
20.05.16
12:59
(102) спор идет за левое соединение )
104 Avalone2010
 
20.05.16
13:00
(100) используеться seek where, означает что отсутствует индекс, идет частичное сканирование таблицы . Далее идет нестед лупс, возможно он не должен там быть. Напишите пожалуйста количество ожидаемых и выводимых строк
105 ViSo76
 
20.05.16
13:00
(99) Я писал в (87) (103) За левое не идёт спора, я уже написал, если есть услуги в отдельной таблице то внутреннее.
106 GenAcid
 
20.05.16
13:01
(95) Ты умными словами не раскидывайся, везде нужно голову включать: нужно сравнить сколько раз добавляется документ, и сколько раз по нему отчет будет формироваться, после этого принимать решение по индексу.

PS Регистр по сути даст тот же тот же индекс только в отдельной таблице, и внезапно, падения производительности на этом практически не будет.
107 ViSo76
 
20.05.16
13:03
(106) Зачем раздувать базу? Зачем лишнее писать в доп таблицу? Внезапно много зачем
108 Kolyasik
 
20.05.16
13:05
(104) на какой момент?
109 Тролль главный
 
20.05.16
13:06
(92) тупанул чето
110 Avalone2010
 
20.05.16
13:08
по первым сик веа, и нестед лупса.(нижнии три операции) и для сорт бая его стоимость, и стоимость всего запроса в целом
111 Avalone2010
 
20.05.16
13:08
(110) к (108)
112 ILM
 
гуру
20.05.16
13:10
Идите все в регистры))) - они оптимизированы для запросов через 1С.
113 GenAcid
 
20.05.16
13:11
(107) Я, таки, одобряю ваш подход к ресурсам сервера. Гои могут подождать свои отчеты пару дней, а сервера нынче очень дороги.
114 Kolyasik
 
20.05.16
13:12
(104) табл док, 12000, тч 11
вложенные циклы 144к
сортировка 0,009%
115 ViSo76
 
20.05.16
13:13
(112) Ты имеешь ввиду особенные таблицы в РСУБД? ( не только лишь все мало кто может это сделать :)
116 Avalone2010
 
20.05.16
13:14
ого.Смотри у тебя на нестед лупсе просто пидец!
117 ViSo76
 
20.05.16
13:15
(114) А что за циферки будут для (79)?
118 Kolyasik
 
20.05.16
13:16
не увлекайтесь, дайте поработать
119 ViSo76
 
20.05.16
13:17
(113) Очередной раздуватель из мухи слона?
120 Avalone2010
 
20.05.16
13:18
(116) для него оптимально 5-6 выполнений. Оптимизатор пипец как просчитался. у тебя получается идет 11 раз частичное сканирование 12к строк таблицы(если не ошибаюсь). а сколько строк всего возвращается в итоге?
121 GenAcid
 
20.05.16
13:23
(113) Сначала проверь насколько увеличится база и насколько замедлится insert после добавления одного индекса по реквизиту с типом булево (допустим в таблицу с 100000 документов), потом расскажешь про мух и слонов.
122 Avalone2010
 
20.05.16
13:24
(121) а зачем по булево индексировать, там же селективность никакая?
123 ViSo76
 
20.05.16
13:30
(122) Я думаю что этот индекс тупо будет проигнорирован в плане и увеличит время INSERT-а, будет занимать место на диске и да "гои" (113) так и не дождутся своего отчёта
124 GenAcid
 
20.05.16
13:34
(122) (123) А вы попробуйте из базы в 100000 записей выбрать 500 у которых это булево установлено. Вы тут теории двигаете, а я на практике проверял.
125 ViSo76
 
20.05.16
13:37
(124) Мы обсуждаем данный запрос или абстракцию? Перечитай (38) по поводу абстракций. Так и хочется сказать словами Лаврова.
126 Kolyasik
 
20.05.16
13:43
(120) 250 строк на финише
127 Kolyasik
 
20.05.16
13:47
+ (126) база ерп большая и старенькая, статистику обновлю еще гляну позже
128 Avalone2010
 
20.05.16
13:54
(127) В принципе все что выше написали по поводу регистра и индексации верно, если что пишите на мейл, поковыряю планы.
129 ViSo76
 
20.05.16
13:55
(127) Спасибо за участие и пожалуйста выложи просьбу в (117), моего запроса в (12) только с INNER JOIN чтобы сравнить с (0)
130 profitmaker
 
20.05.16
13:57
Господа, мне кажется подход неверный изначально. Делать запрос к документу - моветон. Изначально должен быть запрос к Оборотному регистру накопления ибо это продажи, ибо это документ РТУ. Если конфа ERP тогда запрос по оборотному регистру ВыручкаИСебестоимостьПродажОбороты
131 profitmaker
 
20.05.16
14:00
Если это УПП то там есть оборотный регистр накопления ПродажиСебестоимость, делай запрос к виртуальной таблице ПродажиСебестоимостьОбороты
132 ViSo76
 
20.05.16
14:01
(130) Да только там данных изначально больше, дефрагментация таблицы может быть больше, индексы толще( можно конечно уповать на то что они в кэше ) и всё равно из-за поля ПервыйРаз соединять с таблицей Документ.РеализацияТоваровУслуг так что не вижу причин почему запрос не сделать так как в (12)
133 ViSo76
 
20.05.16
14:03
(131) Нет комментариев я в ехере
134 Sonny
 
20.05.16
14:17
Прискорбно, что большинство 1сников не знают 1С.
135 profitmaker
 
20.05.16
15:01
(132) Что мешает ВЫБРАТЬ ПЕРВЫЕ 1 ?
136 profitmaker
 
20.05.16
15:01
Ну и запрос по виртуальной таблице оборотного регистра накопления априори будет отработан быстрее чем к таблице самого документа.
137 profitmaker
 
20.05.16
15:03
(132) Поля ПервыРаз быть не должно, если это костыль статуса, то такой статус должен хранится в Регистре сведений
138 profitmaker
 
20.05.16
15:03
(132) Да и вообще что это за признак, косвенный признак что это первая продажа данному контрагенту? Тогда можно обойтись и без него.
139 brznzglwgn
 
20.05.16
15:08
Попробуй переделать запрос на -
ВЫБРАТЬ
    Док.Ссылка КАК Ссылка
    Поместить ВТ_Документы
ИЗ
    Документ.РеализацияТоваровУслуг КАК Док
ГДЕ
    Док.Проведен
    И Док.Дата МЕЖДУ &ДатаНач И &ДатаКон
    И Док.ПервыйРаз;
    
ВЫБРАТЬ
    РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура,
    СУММА(РеализацияТоваровУслугТовары.Количество) КАК Количество
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
ГДЕ
    РеализацияТоваровУслугТовары.Ссылка В (выбрать Т.Ссылка ИЗ ВТ_Документы КАК Т)

СГРУППИРОВАТЬ ПО
    РеализацияТоваровУслугТовары.Номенклатура
140 profitmaker
 
20.05.16
15:10
(139) по точке запятой предполагаю что это пакетный запрос, тогда не хватает ПОМЕСТИТЬ Т
141 profitmaker
 
20.05.16
15:11
но все это бред, какие то жалкие щенячие попытки реализовать поставленную задачу через костыли абы как
142 profitmaker
 
20.05.16
15:12
делать нужно как правильно, а не тупо абы как лишь бы взлетело
143 profitmaker
 
20.05.16
15:13
Читаем (131) (135) (136) (137) (138)
144 ViSo76
 
20.05.16
15:15
(143) Автор пиши исчо ( фильтр не пропускает точное изречение )
145 brznzglwgn
 
20.05.16
15:20
(139) ну так там есть Поместить ВТ_Документы,
и именно таким методом я ускорял запросы когда внутри ТЧ дофига строк и идут фильтры на Ссылка.
146 ViSo76
 
20.05.16
15:29
(145) Это не тот случай. Запрос в (12) и не нужно временных таблиц, тем более через IN РеализацияТоваровУслугТовары.Ссылка В (выбрать Т.Ссылка ИЗ ВТ_Документы КАК Т)

PS: Ужас какой-то...
147 Kolyasik
 
20.05.16
15:30
(142) тут у (0) есть костыль, и хотят его оптимизировать (146) не ужас
148 ViSo76
 
20.05.16
15:33
(147) Не ужас будет в другом запросе, но не в данном случае
149 brznzglwgn
 
20.05.16
15:47
(148) аа, ты хочешь тоже самое, но без ВТ. Да, можно и так.
150 ViSo76
 
20.05.16
15:50
(149) Я написал запрос в (12) только там внетреннее соединение поставить и это конечный вариант.
151 AneJIbcuH
 
21.05.16
08:42
(124) "Если у нас есть реквизит типа Булево, который мы проиндексировали с целью ускорить получение информации, то это будет очень неэффективно. Потому что Булево имеет всего два значения, и если они равномерно распределены в таблице, то половина таблицы будет со значениями Истина, а другая половина - со значениями Ложь. В результате СУБД не будет использовать такой индекс, потому что она увидит, что ничего полезного она от этого индекса не получит. Подобный индекс будет использоваться только в том случае, если мы хотим выбрать, например, значение Ложь, и записей с таким значением очень мало. Например, 99% это Истина, и 1% это Ложь."
152 GenAcid
 
21.05.16
21:00
(151) Прочитай (8) потом (12). Потом перечитай свой пост внимательно и пойми что нужно думать над каждой конкретной ситуацией, а не кричать что "индексы в конкретных случаях могут замедлять неожиданно".
153 AneJIbcuH
 
23.05.16
04:28
(152) Умник, я не кричу,а лишь привел выдержку из статьи компании 1С, так для размышления.
154 AneJIbcuH
 
23.05.16
04:30
(152) и тебе в догонку (122)
155 GenAcid
 
23.05.16
06:32
(154) Последние два предложения из своей выдержки перечитай. (122) это как раз о случае когда таких записей примерно поровну.
156 AneJIbcuH
 
23.05.16
07:00
(155) Если записей примерно поровну, то прям в выдержке указано: "равномерно распределены в таблице, то половина таблицы будет со значениями Истина, а другая половина - со значениями Ложь. В результате СУБД не будет использовать такой индекс"
157 AneJIbcuH
 
23.05.16
07:05
(155) да про 122 согласен.