|
Как работает этот запрос? | ☑ | ||
---|---|---|---|---|
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 скуль. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |