powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / ON vs WHERE
12 сообщений из 12, страница 1 из 1
ON vs WHERE
    #34166071
Фотография Ex_Soft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всю жизнь считал, что чем больше условий в join'е - тем лучче
Так сказать целевая выборка уменьшается уже на этапе объединения таблиц. Т.е.: если дополнительные условия перенести из ON в WHERE, то объединение будет строиться дольше и получиться, соотвтетственно, больше.
Но вот по жизни... Вот кусок SP:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select    
  C.CLIENT_ID, CP.CLIENT_NAME, CP.COD, CP.CLIENT_TYPE_ID, CP.CLIENT_KIND_ID   
from 
  CLIENTS C 
  left outer join CLIENT_PARAM CP on (CP.CLIENT_INTERNAL_ID=C.CLIENT_INTERNAL_ID)
where 
  (C.RECORD_STATE=@ACTUAL) 
  and (CP.CLIENT_NAME like @CLIENT_NAME or @CLIENT_NAME is null) 
  and (CP.COD like @CLIENT_COD or @CLIENT_COD is null) 
  and (CP.CLIENT_TYPE_ID=@CLIENT_TYPE_ID or @CLIENT_TYPE_ID is null) 
  and (CP.CLIENT_KIND_ID=@CLIENT_KIND_ID or @CLIENT_KIND_ID is null) 
отрабатывает приемлемо
По идее
Код: plaintext
1.
2.
3.
4.
  and (CP.CLIENT_NAME like @CLIENT_NAME or @CLIENT_NAME is null) 
  and (CP.COD like @CLIENT_COD or @CLIENT_COD is null) 
  and (CP.CLIENT_TYPE_ID=@CLIENT_TYPE_ID or @CLIENT_TYPE_ID is null) 
  and (CP.CLIENT_KIND_ID=@CLIENT_KIND_ID or @CLIENT_KIND_ID is null) 
Нуна перевести в условие on join'а - так сказать для уменьшения результата объединения...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select    
  C.CLIENT_ID, CP.CLIENT_NAME, CP.COD, CP.CLIENT_TYPE_ID, CP.CLIENT_KIND_ID   
from 
  CLIENTS C 
  left outer join CLIENT_PARAM CP on (CP.CLIENT_INTERNAL_ID=C.CLIENT_INTERNAL_ID)
                                                   and (CP.CLIENT_NAME like @CLIENT_NAME or @CLIENT_NAME is null) 
                                                   and (CP.COD like @CLIENT_COD or @CLIENT_COD is null) 
                                                   and (CP.CLIENT_TYPE_ID=@CLIENT_TYPE_ID or @CLIENT_TYPE_ID is null) 
                                                   and (CP.CLIENT_KIND_ID=@CLIENT_KIND_ID or @CLIENT_KIND_ID is null) 

where 
  (C.RECORD_STATE=@ACTUAL) 
висит аж до time-out'а...
Я понимаю, что где-то в моих умозаключениях ошибка, но - где
Просветите, pls... Не дайте помереть невченным

_________________
"Helo, word!" - 17 errors 56 warnings
...
Рейтинг: 0 / 0
ON vs WHERE
    #34166103
Бабичев Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да у тебя запросы по результату будут совсем неэквивалентными!
Они у тебя вернут совершенно разные наборы данных :)

А вообще, когда речь заходит об оптимизации, то для начала хотя бы на планы смотрят, чтобы понять что и как пытается сделать сервер...
...
Рейтинг: 0 / 0
ON vs WHERE
    #34166108
Бабичев Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во внешних соединениях меняется роль предикатов и их область действия, в зависимости от того, где они указаны - в ON-clause или в WHERE-clause.
...
Рейтинг: 0 / 0
ON vs WHERE
    #34166123
Фотография Ex_Soft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насчет left outer - sorry... Там там действительно выборки будут совершенно разные. Точнее - NULL'ы. Целевая таблица как была так и останеться. Речь шла о просто JOIN'е...
_________________
"Helo, word!" - 17 errors 56 warnings
...
Рейтинг: 0 / 0
ON vs WHERE
    #34166182
Бабичев Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Указание предикатов в ON или в WHERE меняет суть самого предиката.
В ON - предикат является пре-джойн/джойн предикатом и представляет собой либо пре-фильтр НА ТАБЛИЦУ до объединения, либо условие объединения таблиц.
В WHERE - предикат является пост-джойн предикатом, по сути - фильтром на РЕЗУЛЬТАТ соединения.

То, как сервер проинтерпретирует и соптимизирует эти предикаты - это уже отдельная тема для разбирательства.
ТУт нужно-таки смотреть на план выполнения запроса...
...
Рейтинг: 0 / 0
ON vs WHERE
    #34166535
Фотография Ex_Soft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бабичев Сергей
То, как сервер проинтерпретирует и соптимизирует эти предикаты - это уже отдельная тема для разбирательства.
ТУт нужно-таки смотреть на план выполнения запроса...

Тут вопрос, так сказать, чисто теоретический, а-ля из области общих знаний
Отречемся от оптимизаторов, планов - оставим это на совести разработчиков.

SQL2(92) рекомендует для объеденения таблиц юзать join'ы, а не where, педалируя, опять же-таки, на ту же оптимизацию. Мало того, даже изменяя порядок следования join'ов, можно, типа, как раз и управлять этой оптимизацией. Согласен, что это касается объединений, так сказать, естественных.
Но нигде же не запрещается вносить дополнительные условия в join, ограничивая выборку. По идее (ессесно, никто так в самом деле не делает, разве шо тока студенты, изучая реляционную алгебру), что в случае с естественными соединениями, что в случае с дополнительными условиями, строиться декартово произведение и потом просто тупо отбрасываются записи невыполняющие условие on. Меня просто поразил сам факт того, что
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select    
  C.CLIENT_ID, CP.CLIENT_NAME, CP.COD, CP.CLIENT_TYPE_ID, CP.CLIENT_KIND_ID   
from 
  CLIENTS C 
  join CLIENT_PARAM CP on (CP.CLIENT_INTERNAL_ID=C.CLIENT_INTERNAL_ID)
where 
  (C.RECORD_STATE=@ACTUAL) 
  and (CP.CLIENT_NAME like @CLIENT_NAME or @CLIENT_NAME is null) 
  and (CP.COD like @CLIENT_COD or @CLIENT_COD is null) 
  and (CP.CLIENT_TYPE_ID=@CLIENT_TYPE_ID or @CLIENT_TYPE_ID is null) 
  and (CP.CLIENT_KIND_ID=@CLIENT_KIND_ID or @CLIENT_KIND_ID is null)
oB!!!
а
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select    
  C.CLIENT_ID, CP.CLIENT_NAME, CP.COD, CP.CLIENT_TYPE_ID, CP.CLIENT_KIND_ID   
from 
  CLIENTS C 
  CLIENT_PARAM CP on (CP.CLIENT_INTERNAL_ID=C.CLIENT_INTERNAL_ID)
                                and (CP.CLIENT_NAME like @CLIENT_NAME or @CLIENT_NAME is null) 
                                and (CP.COD like @CLIENT_COD or @CLIENT_COD is null) 
                                and (CP.CLIENT_TYPE_ID=@CLIENT_TYPE_ID or @CLIENT_TYPE_ID is null) 
                                and (CP.CLIENT_KIND_ID=@CLIENT_KIND_ID or @CLIENT_KIND_ID is null) 
where 
  (C.RECORD_STATE=@ACTUAL)
ниасилил

BTW, select @@version
Adaptive Server Enterprise/12.5.1/EBF 11428/P/NT (IX86)/OS 4.0/ase1251/1823/32-bit/OPT/Wed Sep 17 11:10:54 2003

BTW2, нуна проверить на FB - интересно как он себя покажет...
Получается, что внесение дополнительных услових, не касающихся объединения, в join - моветон?
_________________
"Helo, word!" - 17 errors 56 warnings
...
Рейтинг: 0 / 0
ON vs WHERE
    #34166597
Фотография Ex_Soft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В догонку

Если
Бабичев Сергей
В ON - предикат является пре-джойн/джойн предикатом и представляет собой либо пре-фильтр НА ТАБЛИЦУ до объединения , либо условие объединения таблиц.

то, получается, внесение доп условий должно наоборот все улучшить, а не отправлять в down

_________________
"Helo, word!" - 17 errors 56 warnings
...
Рейтинг: 0 / 0
ON vs WHERE
    #34166640
Бабичев Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ex_Soft
Тут вопрос, так сказать, чисто теоретический, а-ля из области общих знаний
Отречемся от оптимизаторов, планов - оставим это на совести разработчиков.
Вот как раз с точки зрения теории - это всё монопинесуально.
В теории всё делается, как ты и писал - строится декартово произведение множеств и лишь затем накладываются условия на результат объединения.

На практике же дела обстоят совсем по другому...
И если есть реальное желание разобраться с причинами неадекватного изменения времени выполнения запроса при изменении нотации его записи, то обсуждение должно строиться строго в привязке к конкретной среде исполнения запроса, в целом, и к оптимизатору, в частности.
...
Рейтинг: 0 / 0
ON vs WHERE
    #34166656
Бабичев Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ex_SoftВ догонку

Если
Бабичев Сергей
В ON - предикат является пре-джойн/джойн предикатом и представляет собой либо пре-фильтр НА ТАБЛИЦУ до объединения , либо условие объединения таблиц.

то, получается, внесение доп условий должно наоборот все улучшить, а не отправлять в down

_________________
"Helo, word!" - 17 errors 56 warningsНе обязательно. Изменив условия запроса, можно было ввести оптимизатор в "заблуждение", повлекшее за собой построение "кривого" плана.
...
Рейтинг: 0 / 0
ON vs WHERE
    #34167319
Volokola
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторНа практике же дела обстоят совсем по другому...
И если есть реальное желание разобраться с причинами неадекватного изменения времени выполнения запроса при изменении нотации его записи, то обсуждение должно строиться строго в привязке к конкретной среде исполнения запроса, в целом, и к оптимизатору, в частности.
К примеру почему оставил в
Код: plaintext
1.
where 
  (C.RECORD_STATE=@ACTUAL) 
а не кинул в ON?
Какая у этого фильтра селективность?
...
Рейтинг: 0 / 0
ON vs WHERE
    #34167960
Фотография Ex_Soft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volokola
К примеру почему оставил в
Код: plaintext
1.
2.
where 
  (C.RECORD_STATE=@ACTUAL) 
а не кинул в ON?

ну... потому что вообще запрос в общем виде выглядит так
Код: plaintext
1.
2.
3.
4.
5.
6.
select    
  C.CLIENT_ID
from 
  CLIENTS C 
where 
  (C.RECORD_STATE=@ACTUAL) 
остальное подтягивается из details-таблицы, которая join'иться. По сему: join'у - join'овое, а where - where'вое

_________________
"Helo, word!" - 17 errors 56 warnings
...
Рейтинг: 0 / 0
ON vs WHERE
    #34169054
Фотография A.K.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В большинстве СУБД использование JOIN ... ON <join condition> или WHERE <join condition> отличается главным образом синтаксически. Ни один оптимизатор для варианта where <join condition> наверное не умудрится сначала построить полное декартово произведение таблиц, а потом из него фильтровать лишнее (хотя с логической точки зрения такая запись обозначает именно это). Подчас оптимизаторы даже подзапросы легко конвертируют в более эффективные JOIN'ы, там где это возможно.

Основная логика внесения JOIN'ов в стандарты была связана с логическим разделением фильтров и соединений, которые до этого "в кучу" записывались в WHERE.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / ON vs WHERE
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]