我怎么知道为什么某个表上的插入很慢?

Bra*_*adC 30 sql-server insert sql-server-2000 database-tuning

我知道 SQL 表上的 INSERT 可能由于多种原因而变慢:

  • 表上存在 INSERT TRIGGERs
  • 许多必须检查的强制约束(通常是外键)
  • 在表中间插入一行时聚集索引中的页面拆分
  • 更新所有相关的非聚集索引
  • 阻止桌子上的其他活动
  • IO 写响应时间差
  • ......我错过了什么?

在我的特定情况下,我如何判断哪个负责?如何衡量页面拆分与非聚集索引更新与其他所有内容的影响?

我有一个存储过程,一次插入大约 10,000 行(来自临时表),每 10k 行大约需要 90 秒。这是令人无法接受的缓慢,因为它会导致其他 spid 超时。

我查看了执行计划,我看到了 INSERT CLUSTERED INDEX 任务和 FK 查找中的所有 INDEX SEEKS,但它仍然没有确切地告诉我为什么需要这么长时间。没有触发器,但该表确实有一些 FKey(似乎已正确索引)。

这是一个 SQL 2000 数据库。

mrd*_*nny 10

有些东西你可以看看...

将批量大小从 10000 减少到更小,例如 2000 或 1000(您没有说明行大小有多大)。

尝试打开 IO Stats 以查看 FK 查找占用了多少 IO。

插入时发生的等待是什么(master.dbo.sysprocesses)?

让我们从这里开始,看看我们要去哪里。

  • 降低批量大小确实有帮助(1000 条记录需要大约 25 秒)。这可能是我们目前的“解决方法”。我会看看我是否可以确定 IO Stats 和等待(当客户端有文件要处理时,作业由客户端按需运行,所以我不能总是预测作业何时实际运行)。 (2认同)

SQL*_*tar 7

布拉德,

您应该检查查询的等待统计信息。使用 SQL2000,您可以使用 DBCC SQLPERF("waitstats") 语法来获取这些详细信息。


yru*_*hka 6

在分析查询性能时,我可以说出我在寻找什么。也许它有帮助。

  • 分析查询执行计划并检查索引扫描、表扫描、sql 数据类型的 convert_implicit 函数的使用、并行性。
  • 使用 SET STATISTICS IO ON 和 SET STATISTICS TIME ON 运行查询以查看每个插入的执行时间和读/写 io。
  • 从 sysprocesses 中查看会话 spid 的等待时间。
  • 运行探查器并选择标准模板。选择以下内容:性能统计(如果重复,那么您的计划会编译多次 - 不好)、RPC:completed、SQL:batchcompleted 和 SQL:batchstarting。向它们添加列rowcounts以准确查看批次中的行数。过滤结果以仅查看您的查询。
  • 最后收集页面预期寿命 从 windows perfmon计数器,如果它低于 300(5 分钟),则 SQL 内存不足。还要收集磁盘计数器:磁盘队列长度磁盘时间(您的数据文件驱动器)、磁盘时间(您的日志文件驱动器)以查看磁盘是否有压力。


And*_*ton 5

尝试使用:

SET STATISTICS IO ON
Run Code Online (Sandbox Code Playgroud)

SET STATISTICS PROFILE ON
Run Code Online (Sandbox Code Playgroud)

统计数据

可用于告诉您哪些表执行了最多的表扫描、逻辑读取和物理读取(我使用这三个来关注查询计划的哪个部分需要最多调整)

统计资料

将主要以表格格式返回查询计划,然后您可以查看 IO 和 CPU 列,了解查询中花费最多的内容(是临时表上的表扫描还是插入到您的表中的排序)聚集键等...)