SQL Server 中的查询优化

Posted

技术标签:

【中文标题】SQL Server 中的查询优化【英文标题】:Query optimization in SQL Server 【发布时间】:2015-08-05 11:12:55 【问题描述】:
SELECT 
    T2.Entity1Id, T1.Entity1Id  
FROM 
    T1  
FULL OUTER JOIN 
    T2 ON T1.c2 = T2.c2 AND T1.c1 = T2.c1 AND T1.c3 = 1
WHERE 
    ((T1.c1 = 123 ) OR (T2.c1 = 123))  
    AND (T1.c3 = 1 OR T1.c3 IS NULL)

以上查询在 SQL Server 2014 中需要 12 秒,有什么想法可以调整查询吗? C1,C2,C3 列上有索引。

观察:在上述查询中,当我从 OR 中删除条件时(即

SELECT  
    T2.Entity1Id, T1.Entity1Id  
FROM 
    T1  
FULL OUTER JOIN 
    T2 ON T1.c2 = T2.c2 AND T1.c1 = T2.c1  AND T1.c3 = 1
WHERE 
    (T1.c1 = 123) AND (T1.c3 = 1 OR T1.c3 IS NULL)

那么它会在 0 秒内返回结果。

每个表大约有 500,000 条记录。

【问题讨论】:

十万 - 请使用 国际知名 计量单位 - 千、百万、十亿......查询的图形执行计划 【参考方案1】:

首先,最后的条件(T1.c3 = 1 OR T1.c3 IS NULL) 是多余的。给定join 条件,这些是唯一可能的值。所以,查询是:

SELECT T2.Entity1Id, T1.Entity1Id  
FROM T1 FULL OUTER JOIN
     T2
     ON T1.c2 = T2.c2 AND T1.c1 = T2.c1  AND T1.c3 = 1
WHERE (T1.c1 = 123 ) OR (T2.c1 = 123)

如果这没有很好的性能,请考虑将其分成两个查询:

SELECT T2.Entity1Id, T1.Entity1Id  
FROM T1 LEFT JOIN
     T2
     ON T1.c2 = T2.c2 AND T1.c1 = T2.c1  AND T1.c3 = 1
WHERE T1.c1 = 123
UNION 
SELECT T2.Entity1Id, T1.Entity1Id  
FROM T2 LEFT JOIN
     T1
     ON T1.c2 = T2.c2 AND T1.c1 = T2.c1  AND T1.c3 = 1
WHERE T2.c1 = 123

有时,单独子查询的优化比full outer join的优化要好得多。

【讨论】:

第一个解决方案没有任何性能改进。但第二个正在做一些改变。谢谢。

以上是关于SQL Server 中的查询优化的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 中的查询优化

SQL Server查询优化中的两个选项

SQL Server - 如何优化此查询?

使用奇怪的查询优化器行为加入 SQL Server 中的视图

SQL Server SQL性能优化之--pivot行列转换减少扫描计数优化查询语句

有关 SQL Server 中的 SQL 查询提示的详细信息