Подзапросы по сравнению с соединениями

Я осуществил рефакторинг медленный раздел приложения, которое мы наследовали от другой компании для использования внутреннего объединения вместо подзапроса как:

WHERE id IN (SELECT id FROM ...)

Пересмотренный запрос работает о 100x быстрее. (~50 секунд к ~0.3) я ожидал улучшение, но кто-либо может объяснить, почему это было настолько решительно? Столбцы использовали в, где пункт был все индексирован. SQL выполняет запрос в где пункт однажды на строку или что-то?

Обновление - Объясняет результаты:

Различие находится во второй части "где идентификатор в ()" запрос -

2   DEPENDENT SUBQUERY  submission_tags ref st_tag_id   st_tag_id   4   const   2966    Using where

по сравнению с 1 индексируемой строкой с соединением:

    SIMPLE  s   eq_ref  PRIMARY PRIMARY 4   newsladder_production.st.submission_id  1   Using index
157
задан simhumileco 12 July 2019 в 05:40
поделиться

13 ответов

"Связанный подзапрос" (т.е. тот, в который, где условие зависит от значений, полученных из строк содержания запроса) выполнится однажды для каждой строки. Несвязанный подзапрос (тот, в который, где условие независимо от содержания запроса) выполнится однажды вначале. Механизм SQL делает это различие автоматически.

, Но, да, объяснять-план предоставит Вам грязную подробную информацию.

159
ответ дан Jeffrey L Whitledge 23 November 2019 в 21:45
поделиться

С подзапросом необходимо повторно выполнить 2-й ВЫБОР для каждого результата, и каждое выполнение обычно возвращает 1 строку.

С соединением, 2-й ВЫБОР возвращает намного больше строк, но только необходимо выполнить его однажды. Преимущество состоит в том, что теперь можно присоединиться на результатах, и присоединяющиеся отношения - то, к чему база данных, как предполагается, способна. Например, возможно, оптимизатор может определить, как воспользоваться лучшим преимуществом индекса теперь.

2
ответ дан Joel Coehoorn 23 November 2019 в 21:45
поделиться

Это не так подзапрос как В пункте, хотя соединения в основе, по крайней мере, механизма SQL Oracle и выполнены чрезвычайно быстро.

2
ответ дан dacracot 23 November 2019 в 21:45
поделиться

Подзапрос, вероятно, выполнял "полное сканирование таблицы". Другими словами, не используя индекс и возвращая слишком много строк, что, Где от основного запроса должны были отфильтровать.

Просто предположение без деталей, конечно, но это - общая ситуация.

3
ответ дан igelkott 23 November 2019 в 21:45
поделиться

Посмотрите на план запросов для каждого запроса.

, Где в и Соединение может обычно быть реализованным с помощью того же плана выполнения, таким образом обычно существует нулевое ускорение от изменения между ними.

4
ответ дан Amy B 23 November 2019 в 21:45
поделиться

Оптимизатор не сделал очень хорошего задания. Обычно они могут быть преобразованы без любого различия, и оптимизатор может сделать это.

4
ответ дан Cade Roux 23 November 2019 в 21:45
поделиться

Куда подзапрос должен выполнить 1 запрос для каждой возвращенной строки. Внутреннее объединение просто должно выполнить 1 запрос.

4
ответ дан Shawn 23 November 2019 в 21:45
поделиться

прежде чем запросы выполняются против набора данных, они проведены через оптимизатор запросов, оптимизатор пытается организовать запрос таким способом, что это может удалить столько же кортежей (строки) от набора результатов так быстро, сколько это может. Часто при использовании подзапросов (особенно плохие), кортежи не могут быть сокращены из набора результатов, пока внешний запрос не начинает работать.

С наблюдением запрос его твердое для высказывания, что было так плохо об оригинале, но мое предположение будет им, было чем-то, что оптимизатор просто не мог сделать намного лучше. Выполнение 'объясняет', покажет Вам метод оптимизаторов для получения данных.

6
ответ дан pfranza 23 November 2019 в 21:45
поделиться

Обычно это - результат оптимизатора, не бывшего способного выяснять, что подзапрос может быть выполнен как соединение, в этом случае, это выполняется, подзапрос для каждой записи в таблице скорее тогда присоединяются к таблице в подзапросе против таблицы, которую Вы запрашиваете. Часть большего количества "enterprisey" базы данных лучше в этом, но они все еще иногда пропускают ее.

4
ответ дан Mark Roddy 23 November 2019 в 21:45
поделиться

Выполните объяснять-план по каждой версии, он скажет Вам почему.

7
ответ дан scotta 23 November 2019 в 21:45
поделиться

Вот пример того, как подзапросы оценены в MySQL 6.0 .

, новый оптимизатор преобразует этот вид подзапросов в соединения.

16
ответ дан Giuseppe Maxia 23 November 2019 в 21:45
поделиться

Вы выполняете подзапрос однажды для каждой строки , тогда как соединение происходит на индексах.

38
ответ дан Sklivvz 23 November 2019 в 21:45
поделиться

Этот вопрос является несколько общим, таким образом, вот общий ответ:

В основном, запросы занимают больше времени, когда MySQL имеет тонны строк для сортировки.

Делают это:

Выполнение ОБЪЯСНЕНИЕ на каждом из запросов (JOIN'ed один, тогда Подзапрошенный), и сообщение результаты здесь.

я думаю, видя, что различием в интерпретации MySQL тех запросов был бы полезный опыт для всех.

4
ответ дан Pete Karl II 23 November 2019 в 21:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: