Ваш запрос на самом деле является оптимальным.
LEFT JOIN
, предложенные другими, хуже, так как они выбирают ВСЕ значения и затем отфильтровывают их.
Скорее всего, ваш подзапрос будет оптимизирован для этого:
SELECT *
FROM Properties p
WHERE NOT EXISTS
(
SELECT 1
FROM Countries i
WHERE i.CountryID = p.CountryID
)
OR
NOT EXISTS
(
SELECT 1
FROM Regions i
WHERE i.RegionID = p.RegionID
)
OR
NOT EXISTS
(
SELECT 1
FROM Areas i
WHERE i.AreaID = p.AreaID
)
, который вы должны использовать.
Этот запрос выбирает не более 1 строки из каждой таблицы и переходит к следующей итерации вправо, когда находит эту строку (т. Е. Если он не находит Country
для данного свойства, он даже не потрудится проверить Region
).
Опять же, SQL Server
достаточно умен, чтобы построить тот же план для этого запроса и ваш первоначальный.
Обновление:
Проверено на 512K
строках в каждой таблице.
Все соответствующие ID
в таблицах измерений - CLUSTERED PRIMARY KEY
, все поля мер в Properties
проиндексированы.
Для каждой строки в Property
, PropertyID = CountryID = RegionID = AreaID
нет фактически отсутствующих строк (наихудший случай с точки зрения времени выполнения).
NOT EXISTS 00:11 (11 seconds)
LEFT JOIN 01:08 (68 seconds)