У меня есть 2 таблицы, как показано ниже:
Заказ
Id, Name
Товар
Id, OrderId, ...
Я хочу отфильтровать все продукты по определенному названию заказа. Мой запрос T-SQL:
SELECT o.Id, o.Name, p.Id
FROM Order o
INNER JOIN Product p ON o.Id = p.OrderId
WHERE o.Name = "TEST"
В моей таблице продуктов может быть тысяча строк, поэтому я считаю, что этот SQL сначала объединяет все заказы со всеми продуктами, а затем ко всему объединенному набору результатов применяется предложение WHERE, чтобы выбрать только те, у которых есть имя TEST.
Будет намного лучше, если SQL сначала отфильтрует таблицу Order по имени «TEST», а затем объединит только эти заказы, а не всю таблицу.
Итак, вопрос в том, как выполнить WHERE до JOIN?
(1) Ваш запрос не соответствует синтаксису SQL Server. Вы уверены, что правильно пометили? (2) Обычно я ожидаю Name в таблице products, а не orders.
Замените двойные кавычки одинарными, чтобы исправить синтаксическую ошибку, и все в порядке. Оптимизатор достаточно умен, чтобы выбрать хороший план для такого запроса. Проверьте план выполнения, как сказал @RogerWolf, чтобы быть уверенным.


Замените оператор where другим условием в части соединения.
что-то вроде этого
SELECT o.Id, o.Name, p.Id
FROM Order o
INNER JOIN Product p ON o.Id = p.OrderId
AND o.Name = 'TEST'
ИЛИ
SELECT o.Id, o.Name, p.Id
FROM (SELECT x.Id, x.Name Order x WHERE x.Name = 'Test') o
INNER JOIN Product p ON o.Id = p.OrderId
Вы не можете указать как SQL запускает запрос, кроме как с использованием подсказок оптимизатора. Стандартный SQL-запрос указывает только результаты, а не план выполнения. Как правило, вы зависите от оптимизатора в выборе наилучшего плана выполнения.
Для этого запроса:
SELECT o.Id, o.Name, p.Id
FROM Orders o INNER JOIN
Product p
ON o.Id = p.OrderId
WHERE o.Name = 'TEST'
Для производительности вам нужен индекс для Orders(Name, Id) и Product(Orderid, p.Id). Это дает оптимизатору инструменты, необходимые для поиска наилучшего плана выполнения.
Они охватывают индексы для запроса, что означает, что все столбцы находятся в индексе, поэтому страницы данных не нужно извлекать. План выполнения должен искать соответствующие заказы на основе Name, а затем извлекать соответствующие строки продуктов.
Спасибо. Есть ли проблема, что мой идентификатор заказа, а также продукт является уникальным идентификатором? Я полагаю, что у меня есть 2 индекса, по одному на каждый первичный ключ (идентификатор), пока я создавал эти таблицы, поэтому мне нужно добавить еще 2, чтобы охватить все поля?
@CSharpBeginner . . . Нет проблем с уникальными идентификаторами запрос. Однако, если вы не инициализируете их правильно, вы можете фрагментировать свою таблицу. Рекомендуемые здесь индексы предназначены для оптимальной производительности. Ваши запросы могут быть в порядке, в зависимости от ваших потребностей в производительности и размера ваших данных.
Вы говорите, что мне нужно создать эти индексы, чтобы дать оптимизатору инструменты. Итак, без этих индексов предложение WHERE не будет выполняться до JOIN, верно? Или все же?
@CSharpBeginner . . . Не могу сказать. Вам нужно посмотреть план выполнения. Однако с правильными инструментами мы более уверены, что оптимизатор выбирает правильный путь. Примечание. Если таблицы небольшие, он все равно может избегать индексов и выполнять полное сканирование таблиц.
Хех, вы можете сказать, «как» это сделать, но это не идея. Я согласен с Гордоном, оптимизатору нужно разрешить (и помочь) выбрать правильный план.
@ДумитрескуБогдан . . . Это действительно хороший момент. Я обновил ответ.
На самом деле я делаю вопрос немного короче, так как таблица Order - это почти то же самое, что у меня есть, но таблица Product получила примерно ~~ 20 полей, поэтому индекс продукта (Id, OrderId) должен быть на самом деле Product (Id, OrderId1, Поле1, Поле2... ПОЛЕ20) ??
@CSharpBeginner . . . Это не имеет значения. Если вы хотите выбрать эти другие поля, запрос должен будет ссылаться на страницы данных, но это не имеет большого значения.
Он должен делать именно то, что вы хотите. Просто проверьте план выполнения, и если это не так, должно быть предложение по индексу.