数据库查询慢问题分析
SQL
数据库跟踪结果分析
局部分析存储过程GSP_GR_UserTakeScore
分析工具: SQL Server Profiler
1. 运行 数据库测试信息 分析对象 GSP_GR_UserTakeScore [Pic 1]
2. 本地 数据库测试信息 分析对象 GSP_GR_UserTakeScore[Pic 2]
对比上面两张图的分析结果 : 根据观察Pic 1中四个框内的信息, 下面逐个分析原因和解决方法(按照图中红框从上到下的顺序)
1. SELECT 语句中使用了 Linked Server 在这里也就是QPAccountsDBLink, 这个技术是针对数据库的分布式使用(link Linked Server), 我们现在使用的主要的三个数据库都没有采用分布式的部署, 所以如果针对这种情况去掉前面的Linked Server此类语句的执行速度回大幅度的提升
问题语句:
SELECT@EnjoinLogon=EnjoinLogonFROMConfineMachine(NOLOCK)WHEREMachineSerial=@strMachineIDAND GETDATE()
处理方案:[运行数据库只是部署在Local之上]
[测试结果:去掉Link Server之后时间消耗是之前的十分之一还少]
[注] 红框1,2 都是同样的情况不再赘述
2. SQL SERVER 在处理的过程中自动添加的inserted 和 deleted表
问题语句:
IF((@insertedScore-@deletedScore)<>0or(@insertedInsure-@deletedInsure<>0))and(@dwUserIDnotin(SELECTUserIDFROMQPAccountsDB.dbo.AccountsInfoWHEREIsAndroid=1))--Profiler中截取
处理方案:Link: Inserted and Deleted
_文章关键参考_ SQL服务器自动创建并管理这些表(inserted, deleted)
Link: 数据库性能优化之SQL语句优化
_文章关键参考_ NOT IN操作符 此操作是强列不推荐使用的,因为它不能应用表的索引。推荐方案:用NOT EXISTS 方案代替
解决法案: 阻止SQL SERVER内部的自动添加表的处理, 不确定可行性, 需要继续深入。
3. 线程阻塞 硬件问题
问题语句:
UPDATEGameScoreInfoSETScore=Score+@VariationScore,InsureScore=InsureScore+@VariationInsure,Revenue=Revenue+@InsureRevenue
问题分析:对比本地的profiler执行结果和server的执行结果(Pic1, Pic2), 发现同样的数据库在Server上引起了80000+的Reads(*Reads: 由服务器代表事件读取逻辑磁盘的次数*)
以及观察SQL SERVER中的执行计划(下图)。未发现异常的情况,
[本地]
[Server]
所以, 推断问题的主要原因是高并发, 也许还有硬件的问题。
处理方案:见下文对Latch_Ex(独占锁的分析).
数据库Thread等待时间分析
分析工具:
我们数据库的线程阻塞情况 [Pic 3]
一般线程阻塞情况 [Pic 4]
问题分析:
可以尝试的解决方案(尚未完成)下一步任务
屏蔽SQL Server的inserted 和 deleted 操作