2010-12-17 5 views
1

У меня есть три способа построения мой запрос:Какой запрос будет самым быстрым?

Первый:

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' 
+0

Вы пробовали бенчмаркинг всех 3? – scunliffe

ответ

1

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

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

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

0

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

Но единственный способ узнать ВАШИ данные - попробовать их и посмотреть.

1

Основным способом выполнения запроса является следующее: FROM (получить все данные) => WHERE (применить ограничения) => SELECT (показать результаты))

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

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

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

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

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

0

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

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 

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

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

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

Смежные вопросы