0

今天同事问了我一个问题

“我有一个包含 4 个选择查询的 SQL 脚本。我每天都在使用它一个多月,但昨天相同的查询花了 2 个小时,我不得不中止执行。”

他的问题是

  • Q1。那天这个剧本怎么了?
  • Q2。我如何检查这 4 个查询,其中哪些被执行,哪些是中止的罪魁祸首?

我对 Q2 的回答是使用 SQL 分析器并检查 Sql 语句事件的跟踪。

Q1:我问了他几个问题

  1. 那天的数据量是多少? 他的回答:没有变化
  2. 索引是否有任何变化,即有人可能放弃了索引?他的回答:没有变化
  3. 它是否通过检查数据管理视图来跟踪它而陷入死锁?他的回答:没有陷入僵局

你认为我还应该考虑问什么?这还有其他原因吗?

由于我没有看到查询,所以我无法将其粘贴到此处。

4

3 回答 3

1

要看的东西(SQL Server):

  1. 统计数据过时了?有人运行大型批量插入操作吗?运行update statistics

  2. 索引的变化?如果是这样,如果它是一个存储过程,请检查执行计划和/或重新编译它......然后再次检查执行计划并更正任何问题。

  3. SQL Server 缓存执行计划。如果您的查询是参数化的或使用 if-then-else 逻辑,第一次运行时,如果参数是边缘情况,则缓存的执行计划对于普通执行可能效果不佳。你可以阅读更多关于这个......啊......功能:

于 2012-12-12T17:53:27.890 回答
0

在这种情况下,我的方法是:

  1. 在这种情况下,他不得不中止执行,因为查询花费的时间超过了预期,最后没有完成。根据我的理解,您正在查询的表可能存在任何阻塞会话/未提交的事务(当天由任何不同的用户执行)。由于您正在执行“select”语句,并且据我所知,“select”语句用于等待任何其他事务完成(如果事务在“select”之前执行)。您的查询可能正在等待任何其他事务完成(事务可能具有更新/插入或删除)。检查阻塞会话(如果有)。

  2. 对于单个会话 sql server 在线程之间切换。您需要检查包含查询的线程是否处于“暂停”/“运行”或“可运行”模式。在您的情况下,您的查询可能处于暂停模式。调查查询的模式以及原因。

  3. 接下来是碎片化。最佳实践是在您的环境中配置索引重建/重组作业,这有助于消除不必要的碎片。这样您的查询在返回数据时将需要扫描更少的页面。否则,您的查询将花费越来越多的时间来返回数据。配置作业并每周至少执行一次作业。它将不断刷新您的索引和页面。

于 2018-07-13T09:22:11.790 回答
-1
  • 使用 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 在他的评论中建议,使用慢查询日志来测量长时间运行的查询的时间。

  • 一旦您确定了长时间运行的查询,请在执行查询时使用查询PROFILER来准确查看它在哪里花费时间。

于 2012-12-12T17:52:59.517 回答