|
Оператор "ИЛИ", конструкция "ВЫБОР" и вероятность фуллскана при них | ☑ | ||
---|---|---|---|---|
0
Drac0
23.05.13
✎
11:04
|
Добрый день!
Насколько известно, например из статьи http://kb.1c.ru/articleView.jsp?id=44#or , наличие логического оператора "ИЛИ" в "ГДЕ" и в условии соединения может приводить к фуллскану. Но вот есть пара вопросов: 1. можно ли где-нибудь найти дополнительные критерии, возникновения этого; 2. помогает ли замена ИЛИ на конструкцию ВЫБОР избежать этого? Например, конструкцию вида "Поле1 = 1 ИЛИ Поле1 = 2" заменить на "ВЫБОР КОГДА Поле1 = 1 ТОГДА ИСТИНА КОГДА Поле1 = 2 ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ" |
|||
1
Ненавижу 1С
гуру
23.05.13
✎
11:07
|
1. почему может, а не всегда приводит?
2. не помогает |
|||
2
Ёпрст
23.05.13
✎
11:07
|
case еще более усугубит ситуацию
|
|||
3
Ненавижу 1С
гуру
23.05.13
✎
11:08
|
помогает "объединить все"
|
|||
4
Drac0
23.05.13
✎
11:13
|
(1) Таки всегда? Или бывают ситуации, когда это безобидно.
(3) Но не в ДС :( |
|||
5
Ненавижу 1С
гуру
23.05.13
✎
11:17
|
(4) что есть ДС?
|
|||
6
1Сергей
23.05.13
✎
11:18
|
(5) демонический список
|
|||
7
Ненавижу 1С
гуру
23.05.13
✎
11:18
|
(6) тогда накуй он нужен такой ))
|
|||
8
Drac0
23.05.13
✎
11:19
|
(7) Да, не, штука хорошая, но вот все эти ограничения делают ее слишком уж узкоспециализированной.
|
|||
9
Drac0
23.05.13
✎
15:29
|
Интересно, а в случае опционального фильтра тоже "ИЛИ" провоцирует фуллскан?
Например, ГДЕ &БезФильтра ИЛИ Таб.Поле1 = &ЗначениеФильтра ? |
|||
10
Wern
23.05.13
✎
15:37
|
На самом деле там не все так очевидно, мс скул, умный, он может и сам разрулить "или" если будет возможность, пробовал, зачастую оптимизатор строит нормальный план. Но вот гарантировать этого нельзя.
|
|||
11
viktor_vv
23.05.13
✎
15:44
|
Если "или" по одному полю, то не так уж все печально.
Если поле попало в индекс, то как правило Index Seek ... Where. |
|||
12
Drac0
23.05.13
✎
15:44
|
(10) Как я понимаю, вероятность выше в простых случаях?
Сейчас в Динамическом списке заменил ИЛИ в условие соединения на подзапрос с объединением (что тоже не особо радует) и получил прирост в скорости в 2-3 раза. |
|||
13
Drac0
23.05.13
✎
15:46
|
(11) В (12) был случай как раз с одним полем:
ПО Таб.Поле1 = &Парам1 ИЛИ Таб.Поле1 = &Парам2 |
|||
14
H A D G E H O G s
23.05.13
✎
15:47
|
Не верьте всему, что пишут на заборе всякие Ненавижу.
Если будет 2 индексированных поля и по ним будет ИЛИ - будет 2 IndexScan |
|||
15
H A D G E H O G s
23.05.13
✎
15:48
|
(9) Будет IndexScan, все норм.
|
|||
16
ИсчадиеADO
23.05.13
✎
15:48
|
работа оптимизатора запроса зависит от версии мс скуля? (ну там обычный или энтерпрайз)?
|
|||
17
H A D G E H O G s
23.05.13
✎
15:49
|
Блин, пардон,
IndexScan читать как IndexSeek |
|||
18
H A D G E H O G s
23.05.13
✎
15:49
|
(16) Нет.
|
|||
19
Пират
23.05.13
✎
15:50
|
(16) работа оптимизатора запроса зависит от версии сервера 1С
|
|||
20
viktor_vv
23.05.13
✎
15:51
|
(14) По двум полям-то скорее всего, а вот по одному полю скорее всего index seek.
(13) В условиях соединения не проверял, смотрел план для where. |
|||
21
H A D G E H O G s
23.05.13
✎
15:51
|
К примеру
ВЫБРАТЬ Номенклатура.код ИЗ Справочник.Номенклатура КАК Номенклатура ГДЕ Номенклатура.код = &код или Номенклатура.Артикул = &Артикул вызовет 2 IndexSeek по индексам с Кодом и Артикулом, потом MergeJoin, а, затем, как ни прискорбно, KeyLookup, ну а что поделать. Но KeyLookup - это мелочи. |
|||
22
Ненавижу 1С
гуру
23.05.13
✎
15:51
|
(14) хз конечно, но когда я писал про
А=Б ИЛИ (А ЕСТЬ NULL И Б ЕСТЬ NULL) мне сказали, что индексам хана |
|||
23
H A D G E H O G s
23.05.13
✎
15:52
|
(20) IndexSeek везде, я опечатался.
|
|||
24
ИсчадиеADO
23.05.13
✎
15:53
|
(19) не, я именно скуль имел ввиду. Слышал, что скорость коррелированных подзапросов как раз зависит от версии
|
|||
25
viktor_vv
23.05.13
✎
15:54
|
(23) Если для этих полей есть отдельные индексы, то да.
|
|||
26
H A D G E H O G s
23.05.13
✎
15:54
|
(21) А вот если 2 поля, и одно - неиндексное - тогда table(clasteredIndex)Scan, без вариантов. Ибо проще один раз табличку посмотреть, чем сначало в индексе шариться, а потом опять таки табличку смотреть.
|
|||
27
H A D G E H O G s
23.05.13
✎
15:55
|
(25) А если - один?
|
|||
28
Drac0
23.05.13
✎
15:57
|
(21) В этом варианте в ИЛИ разные поля, а если будет:
ВЫБРАТЬ Номенклатура.код ИЗ Справочник.Номенклатура КАК Номенклатура ГДЕ Номенклатура.Артикул = &Артикул_1 или Номенклатура.Артикул = &Артикул_2 В этом случае как будет? |
|||
29
H A D G E H O G s
23.05.13
✎
15:58
|
(28) IndexSeek + LookUp
Норм. |
|||
30
acsent
23.05.13
✎
15:59
|
ИЛИ по идексироему полю нормально отрабатывает
|
|||
31
H A D G E H O G s
23.05.13
✎
15:59
|
(30) см (26)
|
|||
32
acsent
23.05.13
✎
16:00
|
(31) по неидексируемым полям ваще без разницы как отбор накладывать.
Хуже уже не будет ))) |
|||
33
viktor_vv
23.05.13
✎
16:02
|
(27) А если один индекс в котором оба поля, то одно из полей по или точно не попадет в индекс.
|
|||
34
Drac0
23.05.13
✎
16:04
|
(29) Тогда почему такие рекомендации в http://kb.1c.ru/articleView.jsp?id=44#or ? Излишняя осторожность?
|
|||
35
H A D G E H O G s
23.05.13
✎
16:04
|
(33) Да, IndexScan.
Это печально. |
|||
36
H A D G E H O G s
23.05.13
✎
16:05
|
(34) Access Denied
|
|||
37
H A D G E H O G s
23.05.13
✎
16:08
|
(32) Ну почему же.
Есть же И |
|||
38
H A D G E H O G s
23.05.13
✎
16:08
|
ВЫБРАТЬ
Номенклатура.Наименование ИЗ Справочник.Номенклатура КАК Номенклатура ГДЕ Номенклатура.код = &код и Номенклатура.Весовой = Истина IndexSeek+KeyLookup Отлично все. |
|||
39
acsent
23.05.13
✎
16:08
|
(37) отбор по неиндексируемым полям - это всегда тайбл скан
|
|||
40
acsent
23.05.13
✎
16:09
|
(38) код - индексируемое поле
|
|||
41
H A D G E H O G s
23.05.13
✎
16:09
|
(40) Я об этом раньше сказал.
|
|||
42
H A D G E H O G s
23.05.13
✎
16:12
|
Короче, речь о том, что
Индексное и Неиндескное поле IndexSeek+Lookup при И TableScan при ИЛИ Оба Индексных 2 IndexSeek полюбому Индексное поле и Константа IndexSeek Несколько условий на индексное поле IndexSeek Общий индекс на 2 поля: IndexScan (это я пока не осмыслил) |
|||
43
Drac0
23.05.13
✎
16:14
|
(36) Цитирую сюда:
"Использование логического ИЛИ в условиях Рекомендации Использование логического ИЛИ в секции ГДЕ запроса Не следует использовать ИЛИ в секции ГДЕ запроса. Это может привести к тому, что СУБД не сможет использовать индексы таблиц и будет выполнять сканирование, что увеличит время работы запроса и вероянтность возникновения блокировок. Вместо этого следует разбить один запрос на несколько и объединить результаты. Например, запрос ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "001" ИЛИ Артикул = "002" следует заменить на запрос ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "001" |ОБЪЕДИНИТЬ ВСЕ |ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "002" Использование ИЛИ в условиях соединения Не рекомендуется использовать логическое ИЛИ в условиях соединения, то есть в секции ПО запроса. Это так же может привести к выбору неоптимального плана и медленной работе запроса. Простого универсального способа переписать такой запрос без использования ИЛИ не существует. Следует проанализировать решаемую задачу и попытаться найти другой алгоритм ее решения. " |
|||
44
viktor_vv
23.05.13
✎
16:16
|
(42)
Общий индекс на 2 поля: IndexScan (это я пока не осмыслил) Тут все просто. Вот структура индекса "Поле1,Поле2" рассматривай "или" как два отдельных условия. В первом случае условие по Поле1 попадет в индекс, так как это поле первое в индексе. А вот отдельное условие по Поле2 не попадет, так как оно второе, а для поля1 значения нет. |
|||
45
acsent
23.05.13
✎
16:17
|
(43) для мс скл - пох
|
|||
46
viktor_vv
23.05.13
✎
16:18
|
(43) Тут ключева фраза "Это может привести к тому, что СУБД не сможет использовать индексы таблиц". Слово "может привести", а может и не привести.
|
|||
47
Drac0
23.05.13
✎
16:21
|
(46) Вот именно этот момент и озадачил при прочтении :)
|
|||
48
H A D G E H O G s
23.05.13
✎
16:22
|
(44) Тоесть, СоставнойИндекс по 2-м полям нужен только для оператора
И ? |
|||
49
acsent
23.05.13
✎
16:24
|
(48) конечно
|
|||
50
H A D G E H O G s
23.05.13
✎
16:25
|
(49) Зато... Зато...
Зато я на велике быстрее гоняю! |
|||
51
Drac0
23.05.13
✎
16:31
|
Хм ... любопытно все это :) Надо, в общем, добраться уже до скуля и смотреть, что там из 1Сных вопросов получается в конкретном случае, а не избегать ИЛИ как огня ...
|
|||
52
Пират
23.05.13
✎
16:32
|
(46) > Это может привести к тому, что СУБД не сможет использовать индексы таблиц
Какие ваши доказательства? |
|||
53
Пират
23.05.13
✎
16:32
|
+(52) > Это может привести к тому, что СУБД ...
А может и не привести? |
|||
54
acsent
23.05.13
✎
16:33
|
(53) 1с не предоставляет доказательств
|
|||
55
Пират
23.05.13
✎
16:34
|
(54) мне очень нравится сочетание "это может привести к тому..."
Жизнеутверждающе. Пойдешь в лес - волк может сожрать, а может и не сожрать :) |
|||
56
Drac0
23.05.13
✎
16:36
|
(54) Дык ,получается, неопределнность возникает на уровне 1С или SQL? Или на данный момент никакой неопределнности нет уже на 100%.
|
|||
57
H A D G E H O G s
23.05.13
✎
16:37
|
(56) Все определено.
|
|||
58
viktor_vv
23.05.13
✎
16:38
|
(52) Я просто привел цитату из рекомендации (43) , это не мое утверждение. А то что может привести или не привести, это выше обсуждалось.
|
|||
59
Пират
23.05.13
✎
16:39
|
> что увеличит время работы запроса и вероянтность возникновения блокировок.
С каких пор грязное чтение вызывает блокировку? |
|||
60
viktor_vv
23.05.13
✎
16:40
|
(56) На сторное SQL, так как план запроса, то есть как получить данные, описанные в запросе решает планировщик скуля, причем на основании достаточно большого количества факторов.
|
|||
61
ptiz
23.05.13
✎
16:41
|
Пути SQL часто неисповедимы.
Долго ломал голову, но так и не победил простейший запрос: ВЫБРАТЬ ... ИЗ РегистрСведений.ЦеныНоменклатурыПоКлиентам КАК ЦеныНоменклатурыПоКлиентам ГДЕ Период <= &Дата И ДатаОкончания >= &Дата И Контрагент = &Контрагент И Активность Строчка "И Активность " - приводит к тормозам, но не всегда, зависит это от погоды на Луне и вспышек на Солнце. Ну и от обновления статистики тоже зависит :) Как обновишь, так появляются тормоза, переставляешь условия местами - всё работает быстро до следующего обновления статистики. Выкинул это условие в итоге от греха подальше. |
|||
62
Пират
23.05.13
✎
16:43
|
(61) работай со срезом, строчка "И Активность" не понадобится
|
|||
63
viktor_vv
23.05.13
✎
16:44
|
(55) Именно так. Причем сам запрос может не меняться, но от входных параметров может меняться план запроса, и скуль уходит в даун.
|
|||
64
H A D G E H O G s
23.05.13
✎
16:45
|
(63) Отличная отмазка.
|
|||
65
Drac0
23.05.13
✎
16:48
|
(64) Т.е. вы на 100% уверены в правильности своего мнения?
Хм, надо бы помоделировать разные ситуации. |
|||
66
Пират
23.05.13
✎
16:49
|
(65) это может привести к тому, что клавиатура поломается
|
|||
67
viktor_vv
23.05.13
✎
16:50
|
(64) Если бы это не было правда. Сам нарывался. Правда на прямых запросах к семерке. Когда ставишь период отчета чуть больше, и скуль уходит в кросс джойн, хотя в самом запросе им и не пахнет.
Там правда слегка кривоватые соединения были, но факт есть. Переписал с использованием временных таблиц, все стало стабильно предсказуемым. |
|||
68
H A D G E H O G s
23.05.13
✎
16:51
|
(65) Нет.
Это я к тому, что в дофига случаев граждане товарищи отнекиваются от разбора полетов и звучит фраза: "SQL выбрал неправильный план запроса, с кем не бывает". Ладно там чьято левая база, но скорее всего даже в своей базе не будут ковырять. |
|||
69
Пират
23.05.13
✎
16:51
|
(67) может просто кривой запрос был?
|
|||
70
H A D G E H O G s
модератор
23.05.13
✎
16:52
|
(66) Это может привести к тому, что Пират покинет эту ветку по причине флуда и отсутствия фраз по делу.
|
|||
71
viktor_vv
23.05.13
✎
16:56
|
(68) Ну это да, железная отмазка :). Но при желании все можно разрулить :).
|
|||
72
Drac0
23.05.13
✎
16:59
|
(68) Ну, тут уже стоит трезво оценивать затраты на копание. Иначе можно все сроки завалить копаясь в интересной, но далеко не глобальной проблеме.
|
|||
73
ptiz
23.05.13
✎
17:02
|
(62) Там такой размер регистра, что от среза как раз пришлось отказаться :)
|
|||
74
H A D G E H O G s
23.05.13
✎
17:02
|
(72) 95% случаев тормозов в моей практике - это ошибки в 1С коде (ДокументВыборка, Обращение через точку (в цикле), Ссылка.Ссылка в Запросе) Это находится на 1-2-3 ЗамеромПроизводительности.
|
|||
75
Drac0
23.05.13
✎
17:06
|
(74) В 1С-ном коде это действительно все просто отыскивается. А вот отладка запроса задача, согласитесь, нетривиальная. Оценить код самого запроса на стороне 1С порой недостаточно.
|
|||
76
viktor_vv
23.05.13
✎
17:10
|
(69) Я и не спорю что кривой. Но факт остается. Абсолютно один и тот же запрос при разных параметрах выполнялся на склуе по разному, именно план запроса строился другой.
|
|||
77
H A D G E H O G s
24.05.13
✎
13:44
|
Вернемся к старым песням....
Вот у меня есть условие мощное, которое по идее должно сводиться к ClusteredIndexSeek и KeyLookup на большую таблицу, а оно сводиться к кривому плану запроса, в котором тока ClusteredIndexSeek с Warning-ом "Columns with no statistics" Вот така фигня, малята. |
|||
78
H A D G E H O G s
24.05.13
✎
13:44
|
Вот запрос:
ВЫБРАТЬ Движения.СерияНоменклатуры, Движения.Номенклатура, Движения.Количество ПОМЕСТИТЬ ДвиженияОбщие ИЗ РегистрНакопления.ТоварыОрганизаций КАК Движения ГДЕ Движения.Период МЕЖДУ &НачалоПериода И &КонецПериода И Движения.Организация = &Организация И Движения.Активность = ИСТИНА И (Движения.Номенклатура, Движения.СерияНоменклатуры) В (ВЫБРАТЬ НоменклатураИСерия.Номенклатура, НоменклатураИСерия.СерияНоменклатуры ИЗ НоменклатураИСерия КАК НоменклатураИСерия) |
|||
79
H A D G E H O G s
24.05.13
✎
13:46
|
Когда я оставляю только
ГДЕ Движения.Период МЕЖДУ &НачалоПериода И &КонецПериода И Движения.Организация = &Организация И Движения.Активность = ИСТИНА тогда - норм, ClusteredIndexSeek |
|||
80
H A D G E H O G s
24.05.13
✎
13:47
|
Вот это я понимаю, SQL построил кривой план запроса, с пояснениями, так сказать :-)
|
|||
81
H A D G E H O G s
24.05.13
✎
13:51
|
(77) Ненене, KeyLookup не должно быть, это же Clustered!
Понапридумывали технологий, блин. Warning "Columns with no statistics" - насколько серьезно? |
|||
82
viktor_vv
24.05.13
✎
13:51
|
А НоменклатураИСерия это что за таблица ?
|
|||
83
viktor_vv
24.05.13
✎
13:53
|
Columns with no statistics это нету статистики, а потому скль в ступоре как делать, ну и делает слегка пальцем в небо.
|
|||
84
H A D G E H O G s
24.05.13
✎
13:53
|
(82) Временная таблица, предварительно отобранная.
|
|||
85
viktor_vv
24.05.13
✎
13:55
|
Может тогда есть смысл проиндексировать ее и внутренним соединением заменить
И (Движения.Номенклатура, Движения.СерияНоменклатуры) В (ВЫБРАТЬ НоменклатураИСерия.Номенклатура, НоменклатураИСерия.СерияНоменклатуры ИЗ НоменклатураИСерия КАК НоменклатураИСерия) |
|||
86
H A D G E H O G s
24.05.13
✎
13:55
|
(83) Обновлял статистику по табличке с Fullscan тока что - бесполезно.
Там уже есть созданная статистика для тех же колонок, что в кластерном индексе. |
|||
87
H A D G E H O G s
24.05.13
✎
13:55
|
(85) Счаст попробую.
|
|||
88
viktor_vv
24.05.13
✎
13:57
|
(85)+ А то это у тебя опять "или" по разным поля, еще и "В". Если еще и НоменклатураИСерия с приличным количеством элементов, то не айс.
|
|||
89
H A D G E H O G s
24.05.13
✎
13:58
|
(88) Нет у меня там ИЛИ
|
|||
90
H A D G E H O G s
24.05.13
✎
13:59
|
(88) ВнутреннееСоединение помогло.
|
|||
91
H A D G E H O G s
24.05.13
✎
13:59
|
(90) Без индексации ВТ
|
|||
92
H A D G E H O G s
24.05.13
✎
13:59
|
Я в шоке.
|
|||
93
viktor_vv
24.05.13
✎
14:00
|
Хотя насчет "или" это я может и погрячился. Не свосем догоняю как это "В" выполнится на скуле.
|
|||
94
H A D G E H O G s
24.05.13
✎
14:00
|
Вот он пример неопределенности Гейзенберга... :-)
|
|||
95
viktor_vv
24.05.13
✎
14:02
|
(92) Ну а че "В" в ГДЕ вполне себе можно представить как перебор с условием в цикле, образно говоря.
|
|||
96
H A D G E H O G s
24.05.13
✎
14:03
|
(95) И? Причем тут тогда этот Warning ?
|
|||
97
viktor_vv
24.05.13
✎
14:08
|
(96) Это у скуля надо спросить :). А в "Или" вполне могло развернуться вот это
(Движения.Номенклатура, Движения.СерияНоменклатуры) В Надо почитать есть ли у скуля подобный синтаксис, или это одинэсовская контрукция, которая потом некоторым образом транслируется. |
|||
98
viktor_vv
24.05.13
✎
14:09
|
(97) Если есть возможность глянь скулевый запрос, получившийся с
(Движения.Номенклатура, Движения.СерияНоменклатуры) В |
|||
99
H A D G E H O G s
24.05.13
✎
14:12
|
(98) вот это условие в sql
AND EXISTS(SELECT 1 FROM #tt2 T2 WITH(NOLOCK) WHERE (T1._Fld18873RRef = T2._Q_001_F_000RRef) AND (T1._Fld18875RRef = T2._Q_001_F_001RRef)) |
|||
100
H A D G E H O G s
24.05.13
✎
14:14
|
как выразился Fragster , это "связанный подзапрос" (вроде так), но он не может подойти к аппарату, он на Нимфостарте...
Походу SQL не может его переварить нормально. |
|||
101
H A D G E H O G s
24.05.13
✎
14:15
|
А сервак у нас на 8.2.17, а 1С вроде обещала в 8.2.18 что то исправить в операторе
В |
|||
102
viktor_vv
24.05.13
✎
14:19
|
(99) А, коррелированный подзапрос, или связанный. Ну таки да, тормознутый он. Как раз к нему и подходит сравнение с запросом в цикле.
|
|||
103
viktor_vv
24.05.13
✎
14:28
|
А попробуй еще разбить, ради эксперимента,
И (Движения.Номенклатура, Движения.СерияНоменклатуры) В (ВЫБРАТЬ НоменклатураИСерия.Номенклатура, НоменклатураИСерия.СерияНоменклатуры ИЗ НоменклатураИСерия КАК НоменклатураИСерия) на И (Движения.Номенклатура В (ВЫБРАТЬ НоменклатураИСерия.Номенклатура ИЗ НоменклатураИСерия КАК НоменклатураИСерия)) И ( Движения.СерияНоменклатуры В (ВЫБРАТЬ НоменклатураИСерия.СерияНоменклатуры ИЗ НоменклатураИСерия КАК НоменклатураИСерия)) и посмотри как он его в скуль переварит. |
|||
104
H A D G E H O G s
24.05.13
✎
14:41
|
(103) переварил норм.
AND T1._Fld18873RRef IN (SELECT T2._Q_001_F_000RRef AS Q_002_F_000RRef FROM #tt4 T2 WITH(NOLOCK)) AND T1._Fld18875RRef IN (SELECT T3._Q_001_F_001RRef AS Q_003_F_000RRef FROM #tt4 T3 WITH(NOLOCK)) Но warning остался. |
|||
105
viktor_vv
24.05.13
✎
14:52
|
А по скорости как ? А warning это наверное к временной таблице, по ней наверное статистику не строит.
|
|||
106
H A D G E H O G s
24.05.13
✎
14:58
|
(105) Ненене, статистики нет по регистратору в кластерном индексе.
|
|||
107
H A D G E H O G s
24.05.13
✎
14:58
|
По времени - никак, не перезапущу я счаст боевой SQL
|
|||
108
viktor_vv
24.05.13
✎
15:12
|
(107) Понятно, спасибо.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |