Как фильтровать строки с предложением WHERE перед JOIN?

У меня есть 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?

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

Roger Wolf 06.07.2019 16:44

(1) Ваш запрос не соответствует синтаксису SQL Server. Вы уверены, что правильно пометили? (2) Обычно я ожидаю Name в таблице products, а не orders.

Gordon Linoff 06.07.2019 16:46

Замените двойные кавычки одинарными, чтобы исправить синтаксическую ошибку, и все в порядке. Оптимизатор достаточно умен, чтобы выбрать хороший план для такого запроса. Проверьте план выполнения, как сказал @RogerWolf, чтобы быть уверенным.

Serg 06.07.2019 16:49
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
3
512
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Замените оператор 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 06.07.2019 16:56

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

Gordon Linoff 06.07.2019 17:01

Вы говорите, что мне нужно создать эти индексы, чтобы дать оптимизатору инструменты. Итак, без этих индексов предложение WHERE не будет выполняться до JOIN, верно? Или все же?

CSharpBeginner 06.07.2019 17:29

@CSharpBeginner . . . Не могу сказать. Вам нужно посмотреть план выполнения. Однако с правильными инструментами мы более уверены, что оптимизатор выбирает правильный путь. Примечание. Если таблицы небольшие, он все равно может избегать индексов и выполнять полное сканирование таблиц.

Gordon Linoff 06.07.2019 17:31

Хех, вы можете сказать, «как» это сделать, но это не идея. Я согласен с Гордоном, оптимизатору нужно разрешить (и помочь) выбрать правильный план.

Dumitrescu Bogdan 06.07.2019 17:37

@ДумитрескуБогдан . . . Это действительно хороший момент. Я обновил ответ.

Gordon Linoff 06.07.2019 17:57

На самом деле я делаю вопрос немного короче, так как таблица Order - это почти то же самое, что у меня есть, но таблица Product получила примерно ~~ 20 полей, поэтому индекс продукта (Id, OrderId) должен быть на самом деле Product (Id, OrderId1, Поле1, Поле2... ПОЛЕ20) ??

CSharpBeginner 06.07.2019 18:06

@CSharpBeginner . . . Это не имеет значения. Если вы хотите выбрать эти другие поля, запрос должен будет ссылаться на страницы данных, но это не имеет большого значения.

Gordon Linoff 06.07.2019 18:09

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