早上测试对性能压测,发现取sequence服务大量超时报错,查询线上的监控SQL:
大量这个查询,我在DeviceID和Isdelete上建有复合索引,应该很快,而且我测试了一下,取值,执行效率很高,不会出现慢的情况。
但是通过SQL Profile工具监控,发现这个sql,执行的CPU和IO都是很高,取出profile监控出来的sql:
exec sp_executesql N'select * from AppCustomerDevice where DeviceID=@DeviceID and IsDelete=0',N'@DeviceID nvarchar(4000)',@DeviceID=N''
原来这条数据查出17多万条数据,所以执行很慢。后来沟通下来DeviceID='' 是一些错误数据,技术可以把这些IsDelete=0的数据改成IsDelete=1,改成1后,按情况SQL应该优化好了,
但是通过SQL Profile工具发现,还是这个sql执行起来很慢,看其执行计划还是走的全表扫描,让技术把这个参数化的写法改成非参数化,但是要发版,后来在@DeviceID=N‘2’ 随便取值还是IO很高。
看情况是执行计划有午,要么固定其执行计划,加上 with(index=索引名),但是发版时间长,感觉就是统计信息不对,
在这个库上执行了一下更新统计信息: EXEC sp_updatestats ,在清空一下缓存: dbcc freeproccache
再次执行,发现用到索引。问题解决。
总结:
1,一直以为建索引就OK,其实要看查询sql这个的数据量有多少,刚好这个查询就是查得最大的,17多万条,而且全部取出,
2,参数化查询后,执行计划未选择最优,可以考虑先更新一下数据库的统计信息 ,在清空一下缓存