|
Оптимизатор скуля - ленивая скотина :) | ☑ | ||
---|---|---|---|---|
0
Fragster
гуру
21.10.15
✎
11:25
|
Досталось в наследство тут. На заметку "молодым".
По большому счету не понятно, чего ему не хватало, ведь известно, какой индекс использовать: ... | И ВЫБОР | КОГДА &ТипПодбора = 1 | Таблица.Поле1 = &Параметр | КОГДА &ТипПодбора = 2 | Таблица.Поле2 = &Параметр ... не работает, а объединение - работает. Усложняет то, что это "форма подбора с динамическим списком". Заменил на объединение, засунутое во вложенный запрос, убрал основную таблицу, переписал обработку выбора. и все стало зашибись. Если бы этот код не вызывался из кучи мест с установкой параметров в тех же внешних местах - правильнее, конечно, было бы использовать отбор компоновки данных, и это позволило бы оставить динамическое считывание данных. В данном случае это не очень важно, так как строк в результате не очень большое количество. И да - просто я тоже ленивая скотина :) |
|||
1
Гёдза
21.10.15
✎
11:27
|
А где план запроса до исправлений?
|
|||
2
Fragster
гуру
21.10.15
✎
11:29
|
(1) кластеред индекс скан против индекс сик
|
|||
3
Fragster
гуру
21.10.15
✎
11:30
|
10 секунд против 0.2
|
|||
4
Fragster
гуру
21.10.15
✎
11:30
|
и это с RLS
|
|||
5
Господин ПЖ
21.10.15
✎
11:35
|
>Заменил на объединение, засунутое во вложенный запрос
креста на тебе нет |
|||
6
trad
21.10.15
✎
12:20
|
(0) т.е. ты бы хотел, что бы оптимизатор, увидев такую конструкцию:
where case when 2=1 then Поле1 = 'ххх' when 2=2 then Поле2 = 'ххх' end понимал, что первую ветвь можно откинуть и подбирать индекс исходя из оставшегося Поле2 = 'ххх' ? |
|||
7
Гёдза
21.10.15
✎
12:22
|
Без доказательств не верим
|
|||
8
aleks_default
21.10.15
✎
12:30
|
Я таки не понял кто здесь ленивая скотина?
|
|||
9
trad
21.10.15
✎
12:32
|
(0) напиши так:
|И ( | &ТипПодбора = 1 И Таблица.Поле1 = &Параметр | ИЛИ | &ТипПодбора = 2 И Таблица.Поле2 = &Параметр |) |
|||
10
Широкий
21.10.15
✎
12:44
|
(9) Тоже самое получится - на скуле будет перебор без индекса
|
|||
11
trad
21.10.15
✎
12:45
|
(10) у меня есть план
|
|||
12
trad
21.10.15
✎
12:48
|
+(11)
2 запроса - 2 плана select top 1 * from _1sjourn (nolock) where 1=1 and idjournal = 0 or 1=2 and iddocdef = 9615 |--Top(1) |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([db].[dbo].[_1SJOURN])) |--Index Seek(OBJECT:([db].[dbo].[_1SJOURN].[JOURNAL]), SEEK:([_1SJOURN].[IDJOURNAL]=0) ORDERED FORWARD) select top 1 * from _1sjourn (nolock) where 2=1 and idjournal = 0 or 2=2 and iddocdef = 9615 |--Top(1) |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([db].[dbo].[_1SJOURN])) |--Index Seek(OBJECT:([db].[dbo].[_1SJOURN].[DOCTYPE]), SEEK:([_1SJOURN].[IDDOCDEF]=9615) ORDERED FORWARD) |
|||
13
trad
21.10.15
✎
12:49
|
+ sql 2k
|
|||
14
Гёдза
21.10.15
✎
12:49
|
(12) А попробуй через кэйс
|
|||
15
trad
21.10.15
✎
12:52
|
(14)
такой кейс как в (0) и (6) tsql не поймет, его надо транслировать несколько по другому, надо смотреть как его одинесина транслирует |
|||
16
trad
21.10.15
✎
12:57
|
(15) а транслирует она его, скорее всего, как то так:
(относительно моей базы) select top 1 * from _1sjourn (nolock) where case when 1=1 then case when idjournal = 0 then 1 else 0 end when 1=2 then case when iddocdef = 9615 then 1 else 0 end end = 1 |--Top(1) |--Clustered Index Scan(OBJECT:([db].[dbo].[_1SJOURN].[PK__1SJOURN]), WHERE:(If 1 then If ([_1SJOURN].[IDJOURNAL]=0) then 1 else 0 else If 0 then If ([_1SJOURN].[IDDOCDEF]=9615) then 1 else 0 else NULL=1)) |
|||
17
Лефмихалыч
21.10.15
✎
13:32
|
(0) не сюрприз, но на вопрос "почему и какого" не отвечу - мне достаточно того, что я об этой особенности знаю и так не делаю.
Вообще выбор - это почти всегда жопа. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |