Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
kikki
Member

Откуда: киккятница
Сообщений: 20681
Мой вопрос ликбезный по SQL. Правильно ли я понимаю, что связанные подзапросы лучше не использовать, и можно вообще обойтись без них с помощью JOIN'ов? Правильно ли я понимаю, что лучше не пользоваться операторами ANY, IN и EXISTS, если под ними помещается подзапрос, а не список введенных вручную значений?

Спасибо. Очень жду ответа.
18 апр 12, 18:03    [12435028]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Если коротко, то вы понимаете не правильно.
18 апр 12, 18:40    [12435219]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Я бы даже добавил, что более того, иногда без подзапросов не обойтись. А, в частности, exists иногда бывает использовать куда лучше чем join. Насчет any или some - знаю об их существовании, но не пользуюсь. in - коварная штука, если применяется not in и в подзапросе возможны значения null. Что касается производительности, общего правила нет, нужно смотреть в каждом конкретном случае. Кстати, оптимизатор, не будь дурак, умеет разворачивать подзапросы, когда это позволительно.
18 апр 12, 19:00    [12435295]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
kikki
Member

Откуда: киккятница
Сообщений: 20681
Спасибо за ответы.

Про связанные подзапросы я спросил потому, что конструировать запрос с несколькими связанными подзапросами трудно, да и читать незнакомый запрос такого рода тоже. Не лучше ли JOIN?

Про IN и EXISTS (особенно последнее) я еще подумаю.

Предлагаю привести примеры, когда без связанного подзапроса не обойтись.
18 апр 12, 20:14    [12435632]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
kikki
Предлагаю привести примеры, когда без связанного подзапроса не обойтись.

Примеров можно придумать много. Первое что приходит в голову, это классическая задача, есть таблица клиентов, есть таблица заказов клиентов. У одного клиента может быть как ни одного так и много заказов. Ну и различные вариации вопроса: 1) вывести клиентов, у которых есть хоть один заказ 2) вывести клиентов, которые заказывали за последний год 3) вывести клиентов у которых сумма заказа больше N. Тут конечно не обязателен именно кореллированный подзапрос, но вопрос - зачем мудрить. Еще очень часто кореллированные подзапросы требуются в джойнах таблицы с самой собой же, и т.д. вы наберите ключевые слова в поиске. На форуме масса примеров.
18 апр 12, 20:44    [12435715]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
invm
Member

Откуда: Москва
Сообщений: 9838
kikki
Про связанные подзапросы я спросил потому, что конструировать запрос с несколькими связанными подзапросами трудно, да и читать незнакомый запрос такого рода тоже. Не лучше ли JOIN?
В чем сложность? Визуальные конструкторы их не поддерживают? Ну так не надо ими пользоваться.
Читаемость текста запроса в гораздо большей мере зависит от форматирования, использования алиасов и стиля именования объектов, чем от наличия подзапросов.
kikki
Предлагаю привести примеры, когда без связанного подзапроса не обойтись.
Вот вам простой пример -- есть некая сущность "Документ", реализованная в БД двумя таблицами: "Шапка документа" и "Состав документа". Напишите запрос, выводящий список документов, у которых есть состав, с использованием exists и без. Потом сравните планы.
18 апр 12, 20:51    [12435746]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
kikki
Member

Откуда: киккятница
Сообщений: 20681
invm,

За пример про EXISTS спасибо.
18 апр 12, 21:17    [12435852]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
Anti semi join проще всего и оптимальнее получить через exists или in. Если использовать для этой задачи left join и фильтр в where то серверу приходится делать лишнюю операцию.
19 апр 12, 09:54    [12437287]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
kikki
Member

Откуда: киккятница
Сообщений: 20681
Мистер Хенки,

То что вы написали, это то же самое (или похожее), что имел в виду invm?
19 апр 12, 18:35    [12441613]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Да, оптимизатор не всегда строит оптимальные планы.
Exists трактуется более однозначно, но занимает много писанины. (SELECT * FROM - явно лишний набор букав в нём)

KO
19 апр 12, 23:07    [12442787]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
kikki
Member

Откуда: киккятница
Сообщений: 20681
Mnior,

По-моему, дело не в _количестве_ писанины, а в отсутствии лишних операций и пригодности написанного к смысловому восприятию. В этом смысле EXISTS хороший.
19 апр 12, 23:27    [12442863]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
kikki
а в отсутствии лишних операций
Mnior
Да, оптимизатор не всегда строит оптимальные планы.
А мог бы.
Не должен прогибаться ...

kikki
и пригодности написанного к смысловому восприятию
Mnior
Exists трактуется более однозначно
Но и "восприятие" вещь немного эфемерная.

Если вы загляните чуть дальше слов "SELECT * FROM - явно лишний набор букав в Exists", то мы увидим синтаксис очень сильно напоминающий JOIN. И вам это ни на что не намекает?

Да есть правило: связки в ON, фильтры в WHERE. Это именно из этой оперы.
Но иногда это чуточку неудобно. Легче в LEFT JOIN добавить условие, чем городить под-запрос.

А ещё в SQL не хватает и других консрукций (10448233, 12204429). Так что эти высказывания граничат с лицемерием.

По буквам: я не спорю, просто не всё так однозначно и явно.
Да я пишу (или стал писать) Exists: semi перевесило и повышение скорости рефакторинга тоже понизил фактор ... лени.
Но вот подзапрос с LEFT - не на столько оправдано для меня лично. Но вот alex2 тут более строг.
IN и под-запросы зло адназначное (только для перечислений). Или я что-то пропустил?
20 апр 12, 00:45    [12443133]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
kikki
Мистер Хенки,

То что вы написали, это то же самое (или похожее), что имел в виду invm?

Я имел ввиду что
select a.*
from  a
         left join b
         on b.id_a = a.id
where b.id is null


работает чуть-чуть медленнее, чем
select a.*
from a
where not exists(select 1 from b where b.id_a=a.id)
20 апр 12, 13:55    [12445546]     Ответить | Цитировать Сообщить модератору
 Re: JOIN'ы vs связанные подзапросы и др. сресдтва  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Mnior
Если вы загляните чуть дальше слов "SELECT * FROM - явно лишний набор букав в Exists", то мы увидим синтаксис очень сильно напоминающий JOIN.
И вам это ни на что не намекает?
Наконец сформулирую ещё важный аргумент. Множественая применимость.
Если JOIN конструкивный элемент запроса, то Exists нет. А это важно.
Вот один из недавних примеров, где это сильно мешает.

Поэтому LEFT JOIN не то что удобнее, просто единственно применим (меньшее зло). Если конечно его можно применить.
CREATE VIEW Bla.vwBla... AS
SELECT	...
	,E.ID	AS E_Bla
FROM	...
	LEFT JOIN Bla.Bla	E ON ...
GO
SELECT	*
FROM	Bla.vwBla
WHERE	E_Bla IS NULL
Всякие CASE-ы курят в сторонке.

Если бы Exists был бы конструктивным элементом языка:
CREATE VIEW Bla.vwBla... AS
SELECT	...
	,E.Has	AS E_Has
FROM	...
	EXISTS(Bla.Bla	X ON ...)E
--	SEMI OUTER JOIN Bla.Bla	X ON ...
GO
SELECT	*
FROM	Bla.vwBla
WHERE	E_Has = 0
Цены бы ему небыло.

+ Кстати, скобки как обычно, необязательны !
FROM	... X
	SEMI [OUTER] JOIN <Object1> S	ON <Expressions S*X>	-- Simple
	SEMI [OUTER] JOIN <Object1> A				-- Multi
	     [INNER] JOIN <Object1> B	ON <Expressions A*B>
					ON <Expressions AB*X>


Рационально ?

PS: &%ять, я просто офигиваю как оно хорошо вписывается в текущую концепрцию синтаксиса/модель.
7 май 12, 19:23    [12521147]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить