SQL Server Join / где порядок обработки

18

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

Пример, если это:

SELECT *
FROM   ( SELECT * FROM table1 WHERE col = @val ) t
INNER JOIN table2 ON col = col2

Быть лучше / быстрее чем:

SELECT *
FROM table1
INNER JOIN table2 ON col = col2
WHERE table1.col = @val

Моя теория заключается в следующем (это может быть неправильной реализацией, я пытаюсь вспомнить из внутренней книги SQL Server 2008, которую я прочитал (MSFT Press)):

  1. Обработчик запросов сначала получает левую таблицу (table1)
  2. Присоединяется ко второй таблице (table2) и формирует декартово произведение, прежде чем отфильтровать необходимые строки (если применимо)
  3. Затем выполняется предложение WHERE, ORDER BY, GROUP BY, HAVING с последним оператором SEELCT.

Так что, если в приведенном выше утверждении № 1 таблица меньше, движку SQL нужно меньше работать при формировании декартовых произведений. Затем, когда вы достигнете оператора where, у вас будет сокращенный набор результатов для фильтрации в памяти.

Я мог быть так далеко от цели, это нереально. Как я уже сказал, это теория.

Твои мысли?

Примечание : я только что подумал об этом вопросе, и у меня еще не было шансов выполнить какие-либо тесты.

Примечание 2 : Меченый , как SQL Server , так как я не знаю ничего об осуществлении MySql и т.д. Пожалуйста , не стесняйтесь ответ / комментарий в любом случае

Стюарт Блэклер
источник

Ответы:

15

Логическая обработка запроса выполняется в MSDN (написано командой Microsoft SQL Server, а не третьими лицами)

1. FROM
2. ON
3. JOIN
4. WHERE
5. GROUP BY
6. WITH CUBE or WITH ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOP

Производная таблица следует за этим, затем внешний запрос делает это снова и т. Д.

Это логично, хотя: не актуально . Независимо от того, как SQL Server на самом деле это делает, эта семантика соблюдается буквально . «Фактический» определяется Оптимизатором запросов (QO), и вы избегаете упомянутого вами промежуточного продукта Cartesion.

Стоит отметить, что SQL декларативен: вы говорите «что», а не «как», как вы бы это делали для процедурного / императивного программирования (Java, .net). Поэтому говорить «это происходит раньше» во многих случаях неправильно (например, допущение коротких замыканий или L-to-R WHERE)

В вашем случае выше, QO будет генерировать один и тот же план независимо от того, как он структурирован, потому что это простой запрос.

Тем не менее, QO основывается на стоимости, и для сложного запроса может потребоваться 2 недели для создания идеального плана. Так что это достаточно хорошо, что на самом деле не так.

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

Я использовал этот трюк на SQL Server 2000, чтобы повысить производительность в 60 раз по отчетным запросам. По мере того, как QO улучшает версию до версии, она становится лучше при работе с этими вещами.

И книга, которую вы упомянули: есть некоторый спор по этому поводу.
См. SO и последующие ссылки: /programming//q/3270338/27535

ГБН
источник
6

SQL-запрос не является процедурным по своей природе, поэтому операторы соединения не обрабатываются сверху вниз. Порядок таблиц в ваших примерах запросов не влияет на план выполнения, так как они логически эквивалентны и генерируют точно такой же план.

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

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

Иногда он ошибается, и вы можете помочь ему сделать лучший выбор за счет улучшения индексации, обновления статистики и применения подсказок. В очень редких случаях вы можете захотеть изменить порядок выполнения, используя подсказку FORCE ORDER, но это следует использовать с осторожностью. Это молоток, чтобы сломать гайку, оптимизатор обычно может быть вовлечен в создание лучших планов, предоставляя ему более качественную информацию.

Марк Стори-Смит
источник