sql - 乱七八糟的SQL语句

标签 sql database sql-server-2005 tsql

我有一个案例,我想选择任何具有无效国家、地区或地区 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 KEYProperties中的所有度量字段都被索引。

对于 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/

相关文章:

javascript - 从 javascript 获取 HTML5 WebDB (Web SQL) 数据库的大小

sql - 想要在现有的选择语句中再添加两列

mysql - 在 mysql 中使用多个 AND 运算符过滤数据

sql - SSIS:升级到 SQL Server 2012 后工作包失败

mysql - 自定义 SQL 查询以获取查看次数最多的图片帖子

MYSQL 从多个表中提取多个值

php - Codeigniter 从数据库填充表

php - 从数据库返回平均评分 (SQL)

sql-server-2005 - Excel 中的 ODS 查询返回虚假列名

sql-server - 在 SQL Server 中删除聚集索引安全吗?