修复慢速运行的SQL查询

use*_*628 3 sql sql-server sql-server-2008

我在很多采访中都被问过这个问题:

如果有人抱怨查询运行缓慢,那么第一步要做什么?

我说我运行sp_who2 <active>并检查运行的查询,以查看哪一个占用了最多资源,以及是否存在任何锁定,阻塞或死锁.

有人可以向我提供他们对此的反馈吗?这是最好的答案还是有更好的方法?

谢谢!

小智 11

这是我多年来一直提出的面试问题之一.请记住,我不使用它作为是/否,我用它来衡量他们的SQL Server知识有多深,以及它们是服务器还是代码集中.

您的答案是如何找到哪个查询运行缓慢,并可能检查服务器资源的原因,以确定它突然运行缓慢.根据您的回答,我会开始将您标记为可操作的DBA类型.这些正是操作DBA在接到服务器突然运行缓慢的调用时执行的步骤.如果这就是我正在面试的那就好了,这就是你要找的东西.一旦你发现死锁,我可能会进一步深入研究解决问题的步骤,但我不希望人们能够走得更远.如果它不是死锁或阻塞,那么更好的答案是捕获执行计划并查看是否存在陈旧的统计数据.参数嗅探也可能正在进行,因此存储过程可能需要"重新编译".这些是我看到DBA遇到的典型问题.我不经常采访DBA,所以也许其他人在这里有更深层次的问题.

如果面试是针对开发人员的工作,那么我希望答案更多地假设我们已经找到了哪个查询运行缓慢,并且它是可重现的.如果需要,我甚至可以继续说明.开发人员可以控制的东西与操作DBA可以控制的东西不同,所以我希望开发人员开始查看代码.

人们通常会建议在此时查看执行计划,因此建议将其作为一个好的答案.我稍后会解释为什么我不一定同意这是最好的第一步.如果受访者确实碰巧在此时提到了执行计划,那么我的后续问题就是询问他们在执行计划中寻找什么.最常见的答案是寻找表扫描而不是寻找,可能显示缺失索引的迹象.这些答案向我展示了使用执行计划的更多经验,这与寻找具有最高百分比和/或寻找粗线的步骤有关.

我发现很多查询调优工作在开始执行计划和解决方案时变得误入歧途,因为调整查询的人不知道他们希望执行计划看起来像什么,只是他们不喜欢他们的那个有.然后,他们将尝试关注看似表现最差的步骤,添加索引,查询提示等,当它可能由于某些其他步骤而导致整个执行计划被颠倒翻转,并且他们正在调整错误片.例如,如果在外键上有三个表连接在一起,而第三个表缺少索引,则SQL Server可能会决定下一个最佳计划是以相反的方向遍历表,因为主键索引存在那里.副作用可能是看起来第一个表是有问题的表,而实际上它是第三个表.

我调整查询的方式,以及我更喜欢听到的答案,就是查看代码并了解代码尝试做什么以及我期望联接如何流动.我开始将查询分解为从第一个表开始的碎片.请记住,我在松散地使用术语"第一"来表示我希望SQL Server启动的表.这不一定是列出的第一个表.然而,它通常是最小的桌子,特别是应用了"where".然后我将逐一添加其他表格以查看是否可以找到查询向南的位置.它通常是一个缺失的索引,没有sargability,基数太低或陈旧的统计数据.如果你作为受访者在上下文中使用这些确切的术语,无论是谁在面试你,你都会提出这个问题.

此外,一旦您对联接的流程有所期望,现在就是将期望与实际执行计划进行比较的好时机.这就是你如何判断一个计划是否已经打开你的方法.

如果我正在回答这个问题,或调整一个实际的查询,我还要补充一点,我喜欢在表上获取行计数,并查看连接中所有列的选择性和"where"子句.我也想看看数据.有时问题在代码中并不明显,但在看到一些数据时会变得明显.