Какой запрос будет самым быстрым? - PullRequest
1 голос
/ 17 декабря 2010

У меня есть три способа построения моего запроса:

Первый:

select obj from table1 where condition1 and obj in (
select obj from table2 where condition2 and obj in (
select obj from table3 where condition3 and obj in (
...
)))

Второй:

select obj from table1 where condition1
and obj in (select obj from table2 where condition2)
and obj in (select obj from table3 where condition3)
...

Третий:

select table1.obj from table1
inner join table2 on table2.obj = table1.obj and table2.condition='condition2'
inner join table3 on table3.obj = table2.obj and table3.condition='condition3'
...
where table1.condition='condition1'

У меня вопросы, если эти запросы дают одинаковый результат и если эти запросы одинаково оптимальны.

Я почти уверен, что первые два запроса дают одинаковый результат, но второй запрос быстрее,Не уверен насчет третьего запроса.

ДОБАВЛЕНО

Существует также другая опция:

select table1.obj from table1
inner join table2 on table2.obj = table1.obj
inner join table3 on table3.obj = table2.obj
...
where
table1.condition='condition1' and 
table2.condition='condition2' and 
table3.condition='condition3'

Ответы [ 4 ]

1 голос
/ 17 декабря 2010

Хотя всегда есть исключения, Вариант 3 почти наверняка является лучшим / первым выбором. В зависимости от ваших индексов и распределений данных планировщик выполнения запросов MySQL будет определять, какой порядок извлекать из таблиц.

В других случаях подзапросы (параметры 1 и 2) выполняются для каждой строки внешнего запроса - они могут быть ужасно неэффективными. Таким образом, после предыдущего оператора вложенные подзапросы (вариант 1) могут быть экспоненциально хуже, чем при использовании подзапросов первого порядка (вариант 2) или обычных объединений (вариант 3).

Обратите внимание, что для INNER JOIN s не имеет значения в отношении производительности или функциональность, если дополнительные условия содержатся в предложениях JOIN или в предложениях WHERE. Следовательно, ваша опция other фактически эквивалентна опции 3.

1 голос
/ 17 декабря 2010

В основном способ выполнения запроса следующий: ОТ (получить все данные) => ГДЕ (применить ограничения) => ВЫБРАТЬ (отобразить результаты)

Предложение JOIN всегда является лучшим выбором для объединения данных, поскольку в предложении WHERE проверяются только данные, соответствующие предложениям JOIN.

В FROM только поле в предложении ON выбирается и тестируется перед получением полных данных для WHERE и SELECT.

В обоих ваших первых примерах для каждого SELECT все содержимое таблиц выбирается для тестов предложения WHERE. Это почти та же проблема для объединения в предложении WHERE.

Оба последних примера кажутся одинаковыми. Я предпочел бы последний, потому что использование предложения ON в третьем примере полезно для RIGHT или LEFT JOIN, но в этом случае оно просто вносит беспорядок в использование условий: FROM: получить точный ресурс, WHERE: применить ограничения .

Это объяснение очень схематично, но я надеюсь, что оно имеет смысл ...

0 голосов
/ 19 декабря 2010

Ну, во-первых, эти запросы не обязательно возвращают одинаковые результаты:

1. SELECT x FROM table1 WHERE x IN (SELECT x FROM table2 WHERE y = foo)

2. SELECT x FROM table1 JOIN table 2 USING x WHERE table2.y = foo

IN () удаляет дубликаты. Таким образом, если table2 содержит 50 значений x, удовлетворяющих условию y = foo, запрос 2 вернет в 50 раз больше строк, чем запрос 1. Это может быть тем, что вы хотите, или нет. Если x равен УНИКАЛЬНО в обеих таблицах, запросы будут давать одинаковые результаты.

подзапросы (параметры 1 и 2) выполняются для каждой строки внешнего запроса

Это, конечно, неправильно, поскольку подзапросы не являются зависимыми подзапросами . В любом случае, он выполнит подзапрос один раз, и его хешируют или сортируют, чтобы исключить дубликаты (как того требует IN ()), а затем используют полученный список для выполнения IN-объединения. MySQL до тех пор, пока в последних версиях не выполнялся повторный запрос для каждой строки, это уже не так. Поскольку MySQL не выполняет хэш-соединения IN, он все равно может быть намного медленнее, чем JOIN.

0 голосов
/ 17 декабря 2010

Я подозреваю, что третий запрос будет самым быстрым.SQL оптимизирован, чтобы сделать JOINS быстрой операцией.

Но единственный способ узнать ваши данные - это попробовать их и посмотреть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...