|   |   | 
| 
 | Как работает этот запрос? | ☑ | ||
|---|---|---|---|---|
| 0
    
        pavlushov 27.01.22✎ 12:51 | 
        ВЫБРАТЬ
 СостоянияПредметовВзаимодействий.Предмет КАК Предмет ИЗ РегистрСведений.СостоянияПредметовВзаимодействий КАК СостоянияПредметовВзаимодействий ГДЕ ИСТИНА В (ВЫБРАТЬ ПЕРВЫЕ 1 ИСТИНА ИЗ РегистрСведений.ПредметыПапкиВзаимодействий КАК ПредметыВзаимодействий ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЖурналДокументов.Взаимодействия КАК ЖурналДокументовВзаимодействия ПО ПредметыВзаимодействий.Предмет = СостоянияПредметовВзаимодействий.Предмет И ПредметыВзаимодействий.Взаимодействие = ЖурналДокументовВзаимодействия.Ссылка И ЖурналДокументовВзаимодействия.Ответственный = &Пар ГДЕ ЕСТЬNULL(ПредметыВзаимодействий.Рассмотрено, ЛОЖЬ) = &Пар2 И ЕСТЬNULL(ПредметыВзаимодействий.РассмотретьПосле, ДАТАВРЕМЯ(1, 1, 1)) <= &Пар3) Всем доброго дня. Наткнулся на такой запрос. Я конечно понимаю что таблица СостоянияПредметовВзаимодействий проверяет наличие записей для каждой своей строки выполняя запрос в условии "ГДЕ". Но как это работает? Почему при соединении таблиц ПредметыВзаимодействий и ЖурналДокументовВзаимодействия внезапно указывается условие соединения с таблицей СостоянияПредметовВзаимодействий? Как эта таблица вообще доступна в этой части запроса? Может быть есть где то объяснение как работают подобные запросы, с картинками и пояснениями? Просто складывается ощущение, что условие ГДЕ работает как соединение в данном случае, для каждой записи основной таблицы стыкуются записи таблицы расположенной в условии. Так и есть по сути? | |||
| 1
    
        acht 27.01.22✎ 12:55 | 
        google://коррелированный+подзапрос     | |||
| 2
    
        Курцвейл 27.01.22✎ 12:59 | 
        Коррелированный подзапрос это какашка от которой надо избавляться как можно быстрее.     | |||
| 3
    
        pechkin 27.01.22✎ 13:01 | 
        (2) далеко не факт     | |||
| 4
    
        acht 27.01.22✎ 13:05 | 
        (2) Все врут     | |||
| 5
    
        pavlushov 27.01.22✎ 13:07 | 
        (1) спасибо!     | |||
| 6
    
        pavlushov 27.01.22✎ 13:22 | 
        Это что, получается запрос в цикле?     | |||
| 7
    
        exwill 27.01.22✎ 13:26 | 
        (6) Все так. Одно только дополнение.
 Есть соединение, есть условие соединения и есть просто условие. Общее правило таково, что все условия следует указывать в условиях соединения но не в условиях. Потому что просто условия применяются уже к результату соединения таблиц. Если условие соединения перенести в конструкцию ГДЕ, тогда произойдет следующее. Все соединится со всем, т.е. ты получишь декартово произведение двух таблиц (тысяча записей умножить на тысячу записей рано миллион). И уже к этому распухшему результату будет применяться условие ГДЕ. Но внешне для внутреннего соединения результаты всегда будут одинаковы. Левое соединение при таком подходе превратится во внутреннее. И это еще одна причина, по которой условия соединения всегда указываются в конструкции ПО, но не в конструкции ГДЕ. Однако. Есть один случай, когда нам именно постобработка и потребуется. Мы получили результат внешнего (обычно левого) соединения. А в нем могут быть значения типа NULL. И теперь мы хотим наложить фильтр на значения типа NULL (выбрать все, что NULL или все, что не NULL). И для этого мы используем конструкцию ГДЕ. Конструкция ПО нам тут не поможет. Обратите внимание все это касается только внешнего соединения. Для внутреннего продолжает действовать правило: все условия в ПО. Так что ваша интуиция вас не обманула. Данный запрос составлен неграмотно. | |||
| 8
    
        rsv 27.01.22✎ 13:44 | 
        (0) слово истина ? Замени на 1 и будет более понятно.     | |||
| 9
    
        fisher 27.01.22✎ 14:01 | 
        (6) Реальный план выполнения и так из одних циклов состоит. Чудес не бывает. А текст запроса - это не план выполнения, а декларация требуемого результата. Поэтому не надо на этом зацикливаться. Но на "логическом" уровне можно рассматривать это как "запрос в цикле", чтобы понимать какой будет в итоге результат.     | |||
| 10
    
        Ёпрст гуру 27.01.22✎ 14:05 | 
        (2) жалко только, что в селект листе товарищи с Селезнёвки так его и не реализовали     | |||
| 11
    
        arsik гуру 27.01.22✎ 14:06 | 
        (7) Мне кажется что планировщик скуля обнаруживает такие неоптимальные соединения и накладывает условие на соединение. Но правильно конечно в соединении указать.     | |||
| 12
    
        fisher 27.01.22✎ 14:07 | 
        (7) Какая многословная чушь.     | |||
| 13
    
        arsik гуру 27.01.22✎ 14:08 | 
        +(11) Не планировщик, а оптимизатор.     | |||
| 14
    
        exwill 27.01.22✎ 14:11 | 
        (12) Внутреннее соединение видите? ГДЕ видите? По существу есть, что возразить?     | |||
| 15
    
        Жан Пердежон 27.01.22✎ 14:14 | 
        (0) условие в ГДЕ проверяется для каждой строки результирующей таблицы и было бы странно, если бы таблица "СостоянияПредметовВзаимодействий" была бы там не доступна
 Как то работает - надо смотреть план запроса (ну и уметь читать его заодно) | |||
| 16
    
        Ёпрст гуру 27.01.22✎ 14:15 | 
        (14) в данном конкретном случае, от переноса условия в ГДЕ в секцию ПО план запроса не поменяется от слова совсем.     | |||
| 17
    
        acht 27.01.22✎ 14:18 | 
        (14) 
 Еще будучи ребенком Я узнал один секрет Как-то утром поделился Мудростью со мною дед | |||
| 18
    
        exwill 27.01.22✎ 14:19 | 
        (16) Но лучше все же писать грамотно. Хотя бы для того, чтобы не ломать голову: этот наш случай он "данный конкретный" или не "данный конкретный". Да и буквы экономятся. Как видите, во всех смыслах лучше     | |||
| 19
    
        Жан Пердежон 27.01.22✎ 14:20 | 
        (7) иногда лучше жевать...
 для внутреннего соединения разницы-то как раз и нет: указывать условие в ПО или в ГДЕ разницы нет ни для результата запроса, ни для плана выполнения, ни для времени | |||
| 20
    
        exwill 27.01.22✎ 14:23 | 
        (19) Согласен. Сейчас все оптимизаторы такое исправляют. Но зачем делать ошибку?     | |||
| 21
    
        fisher 27.01.22✎ 14:28 | 
        (14) По существу не "все условия следует указывать в условиях соединения но не в условиях". В общем случае результат получится разный. И не стоит заниматься никакими предварительными фантазийными оптимизациями, исходя из воображаемых представлений о работе внутренних механизмов. План выполнения в общем случае не завязан намертво на декларацию результата. И если результат запроса не зависит от места размещения условия, то план выполнения может получиться или такой же или не менее эффективный. Естественно, не стоит явные условия соединения переносить в ГДЕ - это и читается хуже и затруднит работу оптимизатору, увеличивая вероятность построения неоптимального плана. На условия соединений много эвристик завязано.
 Но общие правила написания запросов - следовать скорее читабельности текста декларации, чем каким-то своим фантазиям о том, как именно он будет выполняться. Особенно если это в ущерб читабельности. Только если точно знаешь, что делаешь и зачем. Есть общие правила типа держать в голове, попадает условие в индекс или нет. Для тяжелых запросов стараться заменять ИЛИ в условиях на группировку объединений. Типа такого, но не глубже. Остальное - это уже удел тонких оптимизаций если действительно попадаешь на узкие места производительности. Но там возможно правильнее будет не запрос хитровывернуто переписывать, а архитектурные изменения внести. | |||
| 22
    
        Жан Пердежон 27.01.22✎ 16:02 | 
        (20) Какую ещё ошибку? Никто ничего не исправляет. Это функционально одно и тоже, хоть бы стандарт заглянул     | |||
| 23
    
        youalex 27.01.22✎ 16:11 | 
        (18) В данном конкретном случае используется (как минимум) эмуляция exists (where 1 in (select  top 1 1))
 А такое нагляднее размещать именно в where | |||
| 24
    
        pavlushov 27.01.22✎ 16:18 | 
        (22) Что за стандарт? Где найти?     | |||
| 25
    
        exwill 27.01.22✎ 16:41 | 
        (23) Я про другое ГДЕ, которое внизу. К верхнему вопросов нет     | |||
| 26
    
        rsv 27.01.22✎ 19:33 | 
        (24) стандарт он один . Омериканцы придумали.
 ANSI SQL. Как обычно все читабельнее на msdn применительно к ms скуль. | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |