我的同事今天问我一个问题
“我有一个包含4个选择查询的SQL脚本。我一直在使用它 每天超过一个月,但昨天相同的查询花了2个小时 我不得不中止执行。“
他的问题是
我对Q2的回答是使用SQL分析器并检查Sql语句事件的跟踪。
第一季度: 我问他几个问题
你认为我还应该考虑什么?可以有任何其他原因吗?
由于我没有看到查询,所以我无法将其粘贴到此处。
答案 0 :(得分:1)
要注意的事项(SQL Server):
统计数据已过期?有人运行大型批量插入操作吗?运行update statistics
。
索引的变化?如果是,如果是存储过程,请检查执行计划和/或重新编译...然后再次检查执行计划并纠正任何问题。
SQL Server缓存执行计划。如果查询是参数化的或使用if-then-else逻辑,则第一次运行时,如果参数是边缘情况,则缓存的执行计划对于普通执行可能效果不佳。你可以在这里阅读更多关于这个......啊...的功能:
答案 1 :(得分:0)
在这种情况下,我的方法是:
在这种情况下,他不得不中止执行,因为查询所花的时间超过了预期的时间,最终没有完成。据我了解,您正在查询的表可能存在任何阻塞会话/未提交的事务(当天有任何其他用户执行)。由于您正在执行“ select”语句,并且据我所知,“ select”语句用于等待任何其他事务完成(如果该事务在“ select”之前执行)。您的查询可能正在等待任何其他事务完成(该事务可能具有更新/插入或删除)。检查是否有阻止会话。
对于单个会话,sql服务器在线程之间切换。您需要检查包含查询的线程是否处于“已暂停” /“正在运行”或“可运行”模式。在您的情况下,您的查询可能处于暂停模式。调查查询的模式以及原因。
接下来是碎片。最佳实践是在您的环境中配置索引重建/重组作业,这有助于消除不必要的碎片。这样您的查询在返回数据时将需要扫描更少的页面。否则,您的查询将花费越来越多的时间返回数据。配置作业并每周至少执行一次该作业。它将不断刷新您的索引和页面。
答案 2 :(得分:-1)
Use EXPLAIN分析四个查询。这将告诉您优化器将如何使用索引(或不使用索引)。
在语句之间向脚本添加查询SELECT NOW()
,以便您可以测量每个查询所花费的时间。您也可以让MySQL为您做算术,将NOW()存储到会话变量中,然后使用TIMEDIFF()来计算语句的开始和结束之间的差异。
SELECT NOW() INTO @start;
SELECT SLEEP(5); -- or whatever query you need to measure
SELECT TIMEDIFF(@start, NOW());
@Scott在评论中建议使用slow query log来衡量长时间运行查询的时间。
确定长时间运行的查询后,请在执行查询时使用查询PROFILER,以确切了解其花费时间的位置。