Рассмотрим следующие два запроса к базе данных AdventureWorks. Критерии где полностью находятся в индексированных столбцах. Если вы используете критерии OR, обе таблицы получают полное сканирование таблицы. Во втором сценарии критерии разбиваются на два запроса, которые объединяются. Во втором сценарии обе таблицы получают поиск по индексу. Может ли кто-нибудь объяснить, почему SQL не может/не оптимизирует первый запрос для поиска по индексу? Есть ли способы указать SQL выполнять поиск без перезаписи в виде UNION? (Я пробовал индексные подсказки, но безуспешно)
SELECT *
FROM [AdventureWorks2022].[Sales].[SalesOrderHeader] hdr
JOIN [AdventureWorks2022].[Sales].[SalesOrderDetail] dtl ON hdr.SalesOrderID = dtl.SalesOrderID
WHERE hdr.SalesOrderID = 43659 OR dtl.SalesOrderDetailID = 43659
----
SELECT *
FROM [AdventureWorks2022].[Sales].[SalesOrderHeader] hdr
JOIN [AdventureWorks2022].[Sales].[SalesOrderDetail] dtl ON hdr.SalesOrderID = dtl.SalesOrderID
WHERE hdr.SalesOrderID = 43659
UNION
SELECT *
FROM [AdventureWorks2022].[Sales].[SalesOrderHeader] hdr
JOIN [AdventureWorks2022].[Sales].[SalesOrderDetail] dtl ON hdr.SalesOrderID = dtl.SalesOrderID
WHERE dtl.SalesOrderDetailID = 43659
Вопросы «почему» часто плохо подходят для Stack Overflow, потому что единственный способ получить авторитетный ответ — это привлечь внимание кого-то, кто действительно работает в команде продукта. Но я могу сказать, что то, что вы видите в случае OR vs UNION, наблюдается в сообществе уже около 20 лет, так что вряд ли это изменится в ближайшее время.
К вашему сведению, union all
снова будет работать лучше union
, если только вам не нужны отдельные строки.
@DaleK - UNION ALL
семантически отличается от WHERE .. OR ..
. UNION
правильно.
@Алекс, я не предполагал... но многие люди не знают разницы между union
и union all
- что определенно стоит знать из соображений производительности.
Я только сейчас заметил, что вы ищете два разных столбца SalesOrderID
и SalesOrderDetailID
— в этом случае поиск необходим по двум разным индексам. Иногда SQL Server может выполнить план объединения индексов, но обстоятельства, при которых он может выполнить это преобразование, я не могу перечислить (хотя я подозреваю, что столбцы должны быть из одной и той же таблицы)
@Алекс, я бы сказал, что UNION ALL
более семантически правильно, чем UNION
, когда дело касается WHERE OR
, потому что UNION
удаляет дубликаты, чего не делает OR. Хотя они тоже не являются точной заменой, это зависит от столбцов
@siggemannen - но это так! Я написал тестовый запрос, прежде чем опубликовать свой первоначальный комментарий;)
@Алекс, см. dbfiddle.uk/8TfRzEiN
Ваша рабочий пример БД - это не то, как выглядят запросы OP. Попробуйте это: dbfiddle.uk/CS7w9C2e. В любом случае это отходит от темы, поскольку никто на самом деле не пытался ответить на вопрос.
Этот ответ Пола Уайта, кажется, объясняет это и подтверждает, что SQL не может создать план UNION
с критериями OR
.
Это преобразование применяется только к одной таблице и не применяется к сравнение атрибутов с атрибутами.
посмотрите план запроса и посмотрите, что «лучше»