我有一个案例,我想选择任何具有无效国家、地区或地区 ID 的数据库条目,无效,我的意思是我的表中不再存在的国家或地区或地区的 ID,我有四个表:Properties、Countries、Regions、Areas。 我想这样做:
SELECT * FROM Properties WHERE
Country_ID NOT IN
(
SELECT CountryID FROM Countries
)
OR
RegionID NOT IN
(
SELECT RegionID FROM Regions
)
OR
AreaID NOT IN
(
SELECT AreaID FROM Areas
)
现在,我的查询是否正确?你有什么建议我可以做什么并以更好的性能实现相同的结果?!
最佳答案
您的查询实际上是最优的。
其他人提出的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)
关于sql - 乱七八糟的SQL语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/747164/