我怎样才能知道为什么在某个表上插入会很慢?


29

我知道,出于多种原因,在SQL表上执行INSERT操作可能会很慢:

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

如何确定我的具体情况中哪个责任人?如何衡量分页与非聚集索引更新与其他所有内容的影响?

我有一个存储的过程,一次插入大约10,000行(从临时表中),每10k行大约需要90秒。这太慢了,因为它会导致其他sps超时。

我已经查看了执行计划,并且看到了INSERT CLUSTERED INDEX任务和FK查找中的所有INDEX SEEKS,但仍不能确定为什么要花这么长时间。没有触发器,但是表中确实有少数FKey(似乎已正确索引)。

这是一个SQL 2000数据库。


是否在数据文件上启用了自动扩展?这可能会导致默认配置出现性能问题。
拉里·科尔曼

我们是在谈论使用探查器吗?msdn.microsoft.com/zh-CN/library/ms187929.aspx
隐身

@Larry:数据文件具有很大的可用空间,所以我认为数据文件的增长不是问题。不过,这是添加到“检查事项”列表中的好方法。
BradC 2011年

@ user210:对语句完成进行概要分析仅向我显示它花费了90秒,但没有告诉我原因。除非您认为还有其他事件更能说明问题。
BradC 2011年

Answers:


10

您可以看的一些东西...

将批次大小从10000减小到较小的值,例如2000或1000(您没有说行的大小)。

尝试打开IO统计信息,以查看FK查询占用了多少IO。

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

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


2
减小批次大小确实有帮助(1000条记录大约需要25秒)。这可能是我们当前的“解决方法”。我将查看是否可以确定IO Stats并等待(该作业是在客户端有文件要处理时由客户端按需运行的,因此我无法始终预测该作业实际何时运行)。
BradC 2011年

7

布拉德

您应该检查查询的等待状态。对于SQL2000,您可以使用DBCC SQLPERF(“ waitstats”)语法来获取这些详细信息。


6

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

  • 分析查询执行计划,并检查索引扫描,表扫描,sql数据类型的convert_implicit函数的使用情况,并行性。
  • 使用SET STATISTICS IO ON和SET STATISTICS TIME ON运行查询,以查看执行时间以及每个插入的IO读写。
  • 从sysprocesses中查询会话spid的等待时间。
  • 运行事件探查器并选择标准模板。选择以下各项:性能统计信息(如果重复执行,则您的计划会被编译很多次-不好),RPC:已完成,SQL:批量完成和SQL:批量启动。向他们添加列行数,以查看批处理中的确切行数。过滤结果以仅查看查询。
  • 最后 从Windows perfmon 收集Page Life Expectancy计数器,如果它低于300(5分钟),则SQL内存不足。还收集磁盘计数器:磁盘队列长度磁盘时间(您的数据文件驱动器),磁盘时间(您的日志文件驱动器),以查看磁盘是否受到压力。

5

尝试使用:

SET STATISTICS IO ON

SET STATISTICS PROFILE ON

统计IO

在告诉您哪个表正在执行最多的表扫描,逻辑读取和物理读取时可能很有用(我使用这三个表来关注查询计划中哪个部分需要最优化)

统计资料

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.