大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说sql性能问题怎么排查_被公司优化还能回去吗,希望您对编程的造诣更进一步.
之前写过一篇博客“SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析”,里面介绍了OR可能会引起全表扫描或索引扫描的各种案例,以及如何优化查询条件中含有OR的SQL语句的几种方法,其实还有一些方法可以用来优化这种问题,这里简单介绍一下。
如下所示,下面的SQL语句之所有出现这种写法,是因为程序的查询界面,可能有多个输入性的查询条件,往往用户只填了一个或部分查询条件(业务情况,应该不用详细介绍,大家都能明白),但是程序里面没有通过判断查询条件生成不同的SQL语句,而是用一个SQL搞定,不管用户没有填写JobNo这个查询条件,下面这种写法:WHERE ISNULL(@JobNo, “”) = “” OR JobNo = @JobNo都能满足条件,实现逻辑功能。
DECLARE @GenerateDateStart DATETIME ,
代码100分
代码100分 @GenerateDateEnd DATETIME ,
@JobNo NVARCHAR(200) ,
代码100分 @GkNo NVARCHAR(200);
SET @JobNo = "PT19B030";
SET @GkNo = "PV19-1-8050";
SELECT *
FROM [dbo].[GEW_UnitConsumption] AS A
LEFT JOIN dbo.UnitConsumption_Relation AS B ON B.UsableFlag = "Y"
AND A.GewUnitConsumptionId = B.RootUnitConsumptionID
WHERE ( ISNULL(@JobNo, "") = ""
OR A.JobNo = @JobNo
)
AND ( ISNULL(@GkNo, "") = ""
OR A.GkNo = @GkNo
);
其实,如果根据查询条件动态生成SQL语句,的确能避免查询条件中出现OR的情形,但是动态SQL语句没有上面语句简单和通熟易懂,尤其是查询条件较多的情况下。只能说各有利弊。这里暂且不讨论那种策略的优劣。
下面介绍一种技巧,如何避免OR引起的索引扫描或全表扫描问题。我们可以使用CASE WHEN改写一下这个SQL语句,就能避免OR引起的执行计划不走索引查找(Index Seek)的情况,如下所示:
DECLARE @GenerateDateStart DATETIME ,
@GenerateDateEnd DATETIME ,
@JobNo NVARCHAR(200) ,
@GkNo NVARCHAR(200);
SET @JobNo = "PT19B030";
SET @GkNo = "PV19-1-8050";
SELECT *
FROM [dbo].[GEW_UnitConsumption] AS A
LEFT JOIN dbo.UnitConsumption_Relation AS B ON B.UsableFlag = "Y"
AND A.GewUnitConsumptionId = B.RootUnitConsumptionID
WHERE CASE WHEN ISNULL(@JobNo, "") = "" THEN A.JobNo
ELSE @JobNo
END = JobNo
AND CASE WHEN ISNULL(@GkNo, "") = "" THEN A.GkNo
ELSE GkNo
END = @GkNo;
测试对比发现性能改善非常明显,当然这种优化技巧也是有局限性的,并不能解决所有OR引起的性能问题(没有银弹!)。如下所示,对于下面这种情况,这种技巧也是无能为力!
SELECT * FROM TEST1 WHERE A=12 OR B=500
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/10816.html