Имя: Пароль:
1C
1С v8
Оптимизатор скуля - ленивая скотина :)
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) не сюрприз, но на вопрос "почему и какого" не отвечу - мне достаточно того, что я об этой особенности знаю и так не делаю.
Вообще выбор - это почти всегда жопа.
Основная теорема систематики: Новые системы плодят новые проблемы.