| 
    
            
         
         | 
    
  | 
Оптимизатор скуля - ленивая скотина :) | ☑ | ||
|---|---|---|---|---|
| 
    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) не сюрприз, но на вопрос "почему и какого" не отвечу - мне достаточно того, что я об этой особенности знаю и так не делаю.
 
        Вообще выбор - это почти всегда жопа.  | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |