ниже приведены два примера, которые почти не отличаются друг от друга, кроме одной детали. меня интересует, какой из них является более быстрым (и правильным) и почему?
примеры упрощенные, схематические.
пример 1
declare @value int
set @value = xxx
select t1.*
from Table t1
join Table2 t2 on (t2.field = t1.field)
where t1.field = @value
пример 2
declare @value int
set @value = xxx
select t1.*
from Table t1
join Table2 t2 on (t2.field = @value)
where t1.field = @value
Здравствуйте, zverjuga, Вы писали: Z>ниже приведены два примера, которые почти не отличаются друг от друга, кроме одной детали. меня интересует, какой из них является более быстрым (и правильным) и почему?
для сферического sql в ваккуумме запросы абсолютно одинаковые. а что мешает посмотреть
Здравствуйте, zverjuga, Вы писали:
Z>ниже приведены два примера, которые почти не отличаются друг от друга, кроме одной детали. меня интересует, какой из них является более быстрым (и правильным) и почему?
На мой взгляд, первый более "правильный", хотя бы потому, что его легче понять, он более читабельный.
Здравствуйте, zverjuga, Вы писали:
Z>приветствую
Z>ниже приведены два примера, которые почти не отличаются друг от друга, кроме одной детали. меня интересует, какой из них является более быстрым (и правильным) и почему? Z>примеры упрощенные, схематические. Z>спасибо заранее за пояснения
Вопрос по сути не имеет смысла, потому что надо смотреть планы запросов. Все остальное — гадание на кофейной гуще.
Вариантов планов для двух даже простых запросов овердохрена, потому что:
1) Три плана джоина
2) Индексы и статистика
3) Эвристики построителя планов, которые в общем случае неизвестны
4) Наличие внешних ключей
5) Значения параметра (особенно когда индексы есть)
Есть подозрение (но только подозрение), что первый пример в большем количестве случаев даст план с меньшей стоимостью.
Z>спасибо заранее за пояснения
Не за что! Лучше скажи: на кой здесь Table2? Для декартова произведения (пример 2)? Или для вывода только в том случае, если @value есть и в Table1 и в Table2 (пример 1)?
В этом случае лучше написать через EXISTS, при правильном индексировании данные Table2 вообще не будут читаться.
Смотри план!
«Национализм во мне столь естественный, что никогда никаким интернационалистам его из меня не вытравить»
Менделеев Д. И.
Здравствуйте, biochemist, Вы писали:
B>Лучше скажи: на кой здесь Table2? Для декартова произведения (пример 2)? Или для вывода только в том случае, если @value есть и в Table1 и в Table2 (пример 1)? B>В этом случае лучше написать через EXISTS, при правильном индексировании данные Table2 вообще не будут читаться.
скорее, этот вариант B>Или для вывода только в том случае, если @value есть и в Table1 и в Table2
плюс в довесок, таких джоинов может быть с десяток. и не просто join, а left join.
Здравствуйте, biochemist, Вы писали:
B>В этом случае лучше написать через EXISTS, при правильном индексировании данные Table2 вообще не будут читаться. B>Смотри план!
Здравствуйте, Слава, Вы писали:
С>Здравствуйте, biochemist, Вы писали:
B>>В этом случае лучше написать через EXISTS, при правильном индексировании данные Table2 вообще не будут читаться. B>>Смотри план!
С>Пожалуйста, напишите пример с EXISTS.
declare @value int
set @value = xxx
select *
from Table t1
where exists (select 'X'
from Table2 t2
where t2.field = t1.field
t2.field = @value)
Как правило, работает быстрее, чем с джоин. Смотри план.
При наличии индекса Table2.field тем эффективней, чем больше колонок в таблице.
PS Звёздочка равнозначна мату: коротко, ёмко, выразительно. Но в продакшен попадать не должна!
«Национализм во мне столь естественный, что никогда никаким интернационалистам его из меня не вытравить»
Менделеев Д. И.
Здравствуйте, _FRED_, Вы писали:
_FR>А какое в данном случае " exists (select *" vs "exists (select 'X'" это имеет значение?
Слово "Х.." может быть написано на заборе, а может в визитке гостя из Поднебесной.
«Национализм во мне столь естественный, что никогда никаким интернационалистам его из меня не вытравить»
Менделеев Д. И.
Здравствуйте, zverjuga, Вы писали:
Z>приветствую
Z>ниже приведены два примера, которые почти не отличаются друг от друга, кроме одной детали. меня интересует, какой из них является более быстрым (и правильным) и почему? Z>примеры упрощенные, схематические.
ЕСЛИ примеры упрощённые, схематические, ТО говорить не о чем.
Можно обсуждать только конкретные , точно выраженные запросы.
Z>пример 1
Z>select t1.* Z>from Table t1 Z> join Table2 t2 on (t2.field = t1.field) Z>where t1.field = @value Z>[/q]
Z>пример 2
Z>select t1.* Z>from Table t1 Z> join Table2 t2 on (t2.field = @value) Z>where t1.field = @value Z>[/q]
Это одинаковые запросы.
Естественно, надо писать по варианту 1, это удобнее и более читаемо.
Не зачем подставлять параметры во все места, где они могут поялвляться,
достаточно одного места в WHERE где мы все их и ожидаем увидеть.
Здравствуйте, rFLY, Вы писали:
FLY>Часто встречаю в exists (select <константа> ...), но ведь работает и с exists (select null ...)
В инструкции к 5-му Ораклу встречал, что это работает быстрее, чем с числом или чем-то другим. В демонстрашках везде Х — далее это вошло в привычку, пишу на автомате.
«Национализм во мне столь естественный, что никогда никаким интернационалистам его из меня не вытравить»
Менделеев Д. И.
Здравствуйте, biochemist, Вы писали:
B>В инструкции к 5-му Ораклу встречал, что это работает быстрее,
Если я ничего не путаю (было где-то в 2006 году), то оракл exist(select null from ...) даже при наличии данных в выборке считал ложью.
PS: Кажется в нашей конторе тоже ораклист завелся. Вчера видел эксист с Х