Производительность SQL: сначала фильтруйте, либо присоединяйтесь первым

У меня есть три таблицы, а именно: сотрудники, отдел и жалоба. Таблица "Сотрудники" содержит более миллиона записей. Мне нужно найти детали сотрудника, его / ее отдел и обиды, поднятые им / ею.

Я мог бы подумать о следующих двух запросах, чтобы найти результат:

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

SELECT * FROM (SELECT * FROM Employees WHERE EmployeeID= @EmployeeID) Emp    
LEFT JOIN Department Dpt ON Emp.EmployeeID= Dpt.EmployeeID    
LEFT JOIN Grievance Grv ON Emp.EmployeeID= Grv.EmployeeID;

2. Присоединяйтесь первым:

SELECT * FROM Employees Emp    
    LEFT JOIN Department Dpt ON Emp.EmployeeID= Dpt.EmployeeID    
    LEFT JOIN Grievance Grv ON Emp.EmployeeID= Grv.EmployeeID    
WHERE EmployeeID= @EmployeeID);

Если мы рассмотрим порядок логической обработки SQL, который начинается с FROM>INNER JOIN>OUTER JOIN>WHERE>....SELECT, первый запрос должен выполняться лучше / быстрее, так как в Inner Query будет только одна запись, и он будет объединен с дальнейшими таблицами. Однако при выполнении обоих запросов я не вижу разницы в производительности, и оба запроса занимают почти одинаковое время.

Не могли бы вы проверить и сообщить мне, где я не так думаю?

4 ответа

Решение

Не беспокойся об этом. Обработка запроса происходит в три этапа:

  1. анализ
  2. компиляция
  3. выполнение

Ключевой частью этапа компиляции является оптимизация. Это когда механизм SQL определяет оптимальный план выполнения.

В вашем первом запросе SQL Server будет игнорировать подзапрос. Два запроса должны иметь одинаковый план выполнения.

Примечание. Это относится не ко всем базам данных. Некоторые более простые базы данных на самом деле материализуют подзапрос.

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

Ваша общая предпосылка - неправильный подход к SQL.

Сначала напишите запрос, и пусть ваша БД разработает план. Оптимизируйте, только если вы обнаружите проблему, иначе вы, как правило, сможете лучше использовать свое время.

План запроса расскажет вам, что происходит.

Не существует "логического порядка обработки", если только вы не имеете в виду "вычисление запроса 1:1 с подвыражениями", но это не имеет значения, поскольку СУБД этого не делает. Ваше неправильное мышление заключается в том, что у вас есть разумная ментальная модель работы СУБД. Читайте про SQL как декларативный. А по поводу выполнения / выполнения запросов - целые книги ждут. Просто будьте прямолинейны в дизайне и запросах и узнайте об индексировании и планах и базовой модели / стратегии вашей СУБД.

Какой запрос более эффективен?

Не имеет значения порядок таблиц, которые вы использовали. Если вы не используете подсказку запроса (FORCE ORDER), которую я бы не рекомендовал. В любом случае, вы лишаете себя возможности оптимизировать план выполнения SQL Server, используя звездочку (*). Используйте только те колонки, которые вам действительно нужны. Перестройте статистику, чтобы убедиться, что в SQL Server достаточно информации для построения оптимального плана выполнения.

Другие вопросы по тегам