AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 157507
Accepted
ajeh
ajeh
Asked: 2016-12-08 10:23:49 +0800 CST2016-12-08 10:23:49 +0800 CST 2016-12-08 10:23:49 +0800 CST

一种跟踪偶尔运行数小时而不是数秒的查询的方法

  • 772

几周或几个月一次,但总是在同一工作日,每日批处理作业中使用的存储过程中的一个查询可能会明显卡住并运行大约 200 分钟,直到应用程序终止其连接。这是一个非常简单的教科书查询,它连接 5 个表并计算sum()一个字段以分配给一个变量,因此在这里提供它没有意义。求和的记录总数一般为1-2打。这个查询没有参数,所以参数嗅探(幸运的是)是不可能的。

我看过很多东西:

  • 数据库中没有在线用户。它纯粹用作数据转储。
  • 没有同时运行的作业。数据库上的最后一个活动是大约提前 10 分钟完成的 tranlog 备份。下一个活动在大约 2 小时后开始,它是一个完整的备份,几分钟后就可以正常完成(虽然这个查询仍然很疯狂)。
  • 此查询运行时有以下锁,均处于 GRANT 状态:

    • OBJECTSch-S锁定模式下请求的表之一
    • HOBT.BULK_OPERATIONS在模式下锁定另一个表
    • OBJECTIX锁定模式下请求的另一个表

该查询(NOLOCK)对所有连接表都有提示。它处于RUNNABLE状态,根据sp_whoisactive,它在服务器上每 15 分钟运行一次,相关查询的 CPU 计数不断增加。CPU 增长到独立查询执行的 1000 倍左右。来自的查询的 IO 与sp_whoisactive我独立运行它时大致相同,但读取计数非常大,是独立执行的 10000 倍。感觉就像查询处于无限循环中。但是,当我早上进入办公室时,作业会在几秒钟内重新运行。

  • 报告的计划sp_whoisactive与独立计划相同。当我运行它时,有一个创建索引的优化器提示,但由于查询独立时间约为 200 毫秒,我并不关心这个提示。实施它似乎又减少了 10 毫秒。

  • DBCC CHECKTABLE在任何涉及的表或上都没有报告错误DBCC CHECKDB。

我对该计划的唯一怀疑是它有两个平行图标。但是添加option (maxdop 1)只会将其执行时间从 200 毫秒增加到 400 毫秒。

涉及到5张表,大小不一,最大的大概有1*10^6条记录,不算大。我们每天凌晨 4 点刷新统计数据和索引,作业在午夜运行,然后再导入任何大量数据。作业本身只添加 1-10 条记录。

强制为挂起的查询存储执行计划会导致相同的结果:查询卡住、巨大的 CPU 和 IO。让优化器发挥它的魔力,或者强制我获得独立的计划(它们是相同的)它在瞬间完成。

...

长话短说:我被允许在此作业的“正常”执行时间内在生产中运行每晚计划的跟踪,以尝试解决此问题。我们不知道下一次发生的时间,只希望它会遵循我们观察到的模式——每隔几周。

我的百万美元问题是我应该追踪哪些事件?我只是一名 SQL 开发人员,没有典型的 DBA 技能,所以我不知道应该通过跟踪暴露 SQL Server 的哪些内部结构以抓住罪魁祸首。

sql-server sql-server-2012
  • 2 2 个回答
  • 280 Views

2 个回答

  • Voted
  1. Best Answer
    Duffy
    2016-12-08T15:11:55+08:002016-12-08T15:11:55+08:00

    根据您的详尽概述,我相信您的表统计信息可能存在问题。

    表仅在通过某些行更新阈值时自动更新其统计信息,对于任何超过 500 行的表,它需要 500+20% 的行进行更改。例如,您的百万行表需要 200,500 行更改才能更新统计信息。

    索引REBUILD将更新表的统计信息(REORGANIZE不是)。

    我认为您的表会随着时间的推移而增长并最终使您的统计信息无效,但不足以触发自动更新。REBUILD但是,在您的查询由于当天早些时候的最后几项更改而开始执行不佳之前,您的重建索引作业不会触发相关表的实际操作。如果您的更改不一致且增量足够小,这将使性能下降一致且突然。在查询运行不佳并且第二天早上一切看起来都很好之后,您的重建索引工作就会解决问题。

    需要检查以确认的事项:

    • 如果您可以捕获“错误”查询计划,请检查管道的实际返回行数与估计返回行数。如果这完全不同,那就是统计问题的危险信号。
    • 检查重新索引作业的条件以确认它没有定期更新查询表上的索引。
    • 如果您可以定期使用以下查询,则可以跟踪统计信息何时更新:
      选择名称作为 index_name
         ,STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
      来自 sys.indexes
      WHERE OBJECT_ID = OBJECT_ID('SchemaName.TableName')
      

    如果您运行的是 SQL Server 2008 R2 Service Pack 1 或更高版本,您可以选择启用记录的跟踪标志 2371以更频繁地动态更新统计信息:

    表中的行数越高,触发统计更新的阈值就越低。例如,如果激活了跟踪标志,则当发生 100 万次更改时,将在具有 10 亿行的表上触发更新统计信息。如果未激活跟踪标志,则具有 10 亿条记录的同一张表在触发更新统计信息之前需要 2 亿次更改。

    对于兼容级别 >= 130 的数据库,从 SQL Server 2016 开始默认启用新行为(即没有跟踪标志)。

    • 3
  2. TT.
    2017-04-07T22:37:02+08:002017-04-07T22:37:02+08:00

    您是否尝试过使用以下任一查询提示运行查询:KEEP PLAN或KEEPFIXED PLAN?

    一旦有了正确的执行计划,KEEPFIXED PLAN就永远不会更改计划,除非基础架构发生更改或在存储过程上运行sp_recompile 。KEEP PLAN只是放宽了重新编译阈值(由于统计数据的变化)。

    请注意KEEPFIXED PLAN,在很长一段时间后,可能会保留一个不足以更改基数的执行计划。

    如果查询中涉及的表的统计数据随时间变化不大(即表的基数和统计数据变化不大),并且问题是一个真正的问题,我可能会看看是否使用fixed plan 是一个长期的解决方案,只要简单地尝试很长时间。它要么在某个时候再次中断(该计划开始对基础数据不利),我将开始寻找另一种解决方案。如果它没有破裂,那么对我来说就足够了。

    • 1

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve