记一次SQL语句执行性能调优

问题描述:

今天在解决项目上面的一个问题是。遇到一个非常奇怪的问题:
如下的sql语句


SELECT COUNT
	( * ) AS totalnum 
FROM
	requestbase r 
WHERE
	EXISTS (
	SELECT
		1 
	FROM
		requestlog wl 
	WHERE
		wl.requestid= r.id 
		AND wl.logtype NOT IN ( '402881e50c5b4646010c5b5afd170009', '402881e50c5b4646010c5b5afd17000e' ) 
		AND wl.operator = 'HRMRESOURCEECOLOGYAAAA0000000009' 
	) 
	AND r.isdelete= '0'

只是wl.operator = ‘HRMRESOURCEECOLOGYAAAA0000000009’ 的条件不同,执行时间却相差超级多。

问题原因:

通过查阅资料,分析不同条件下的sql执行计划:
以下是执行时间较短的执行计划:
在这里插入图片描述
以下是执行时间较长的:

在这里插入图片描述
只是ID不一样,但是其执行计划却不一样。
而图二使用了Clustered Index Seek(聚集索引查找),理论上效率应该更高才对。但是此处估计是因为requestbase 表中的数据量比较多(有40多万条),直接使用其聚集索引查找反而效率不如第一个执行计划,第一个执行计划通过 requestlog 的logtype索引将其先限制住。

解决方法:

利用查询提示(Hint)引导语句执行,此处使用的是 OPTIMIZE FOR 提示,引导语句按照相应ID的执行计划执行。
但是个人觉得要慎用。

DECLARE  @test NVARCHAR(50)
SET @test='8aa0a19e4c226cbc014c253544ce07cd'
SELECT COUNT
	( * ) AS totalnum 
FROM
	requestbase r 
WHERE
	EXISTS (
	SELECT
		1 
	FROM
		requestlog wl 
	WHERE
		wl.requestid= r.id 
		AND wl.logtype NOT IN ( '402881e50c5b4646010c5b5afd170009', '402881e50c5b4646010c5b5afd17000e' ) 
		AND wl.operator = '8aa0a19e4c226cbc014c253544ce07cd'--'8aa0a19e635e5560016367f40ac106b9'
	) 
	AND r.isdelete= '0'
	OPTION(OPTIMIZE FOR(@test='HRMRESOURCEECOLOGYAAAA0000000009'))
	



遗留问题:

1.requestlog这张表的数据量同样不少?为什么这样的执行计划执行效率高那么多?
2.有没有可能从语句执行上面进行优化?
本人试过使用如下的sql语句进行替换,本以为语句能有稍稍有些优化,但实际效果竟然比上述的语句还要慢200ms左右。
权且留作后续分析吧。

select count(*) from requestbase r , requestlog r1
where
 r.id = r1.requestid
and r.ISDELETE = '0'
and r1.operator = 'HRMRESOURCEECOLOGYAAAA0000000004'
and r1.logtype <> '402881e50c5b4646010c5b5afd170009'
and r1.logtype <> '402881e50c5b4646010c5b5afd17000e'









参考:
SQL Server调优系列玩转篇
如何看懂SQL SERVER执行计划

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值