在SQL Server中删除240行11秒

Ian*_*oyd 7 sql-server sql-server-2000

我正在运行删除声明:

DELETE FROM TransactionEntries
WHERE SessionGUID = @SessionGUID
Run Code Online (Sandbox Code Playgroud)

删除的实际执行计划是:

Execution Tree
--------------
Clustered Index Delete(
   OBJECT:([GrobManagementSystemLive].[dbo].[TransactionEntries].IX_TransactionEntries_SessionGUIDTransactionGUID]), 
   WHERE:([TransactionEntries].[SessionGUID]=[@SessionGUID])
)
Run Code Online (Sandbox Code Playgroud)

该表是聚集的SessionGUID,因此240行在物理上在一起.

该表没有触发器.

该操作需要:

  • 持续时间:11821毫秒
  • CPU:297
  • 阅读:14340
  • 写道:1707

该表包含11个索引:

  • 1聚集索引(SessionGUID)
  • 1个唯一(主键)索引
  • 9个其他非唯一的非聚集索引

我怎么能弄清楚为什么这个delete操作正在执行14,340读取,需要11秒?

  • Avg. Disk Read Queue Length河段0.8
  • Avg. Disk sec/Read不超过4ms
  • Avg. Disk Write Queue Length河段0.04
  • Avg. Disk sec/Write不超过4ms

其他读物有哪些?执行计划没有说明它正在阅读什么.


更新:

EXECUTE sp_spaceused TransactionEntries

TransactionEntries  
  Rows      6,696,199
  Data:     1,626,496 KB (249 bytes per row)
  Indexes:  7,303,848 KB (1117 bytes per row)
  Unused:      91,648 KB    
            ============
  Reserved: 9,021,992 KB (1380 bytes per row)
Run Code Online (Sandbox Code Playgroud)

随着1,380每行的字节,而240行,这就是340 kB被删除.

反直觉,340 kB可能会如此困难.

更新二:碎片

Name                           Scan Density  Logical Fragmentation
=============================  ============  =====================
IX_TransactionEntries_Tran...  12.834        48.392
IX_TransactionEntries_Curr...  15.419        41.239
IX_TransactionEntries_Tran...  12.875        48.372
TransactionEntries17           98.081         0.0049325
TransactionEntries5            12.960        48.180
PK_TransactionEntries          12.869        48.376
TransactionEntries18           12.886        48.480
IX_TranasctionEntries_CDR...   12.799        49.157
IX_TransactionEntries_CDR...   12.969        48.103
IX_TransactionEntries_Tra...   13.181        47.127
Run Code Online (Sandbox Code Playgroud)

我进行了碎片整理 TransactionEntries17

DBCC INDEXDEFRAG (0, 'TransactionEntries', 'TransactionEntries17')
Run Code Online (Sandbox Code Playgroud)

因为INDEXDEFRAG是" 在线操作 "(即它只持有ISIntent共享锁).我打算对其他人进行手动碎片整理,直到业务操作调用,说系统已经死了 - 他们转而在纸上做所有事情.

怎么说你; 50%的碎片,只有12%的扫描密度,导致可怕的索引扫描性能?

JNK*_*JNK 5

正如@JoeStefanelli在评论中指出的那样,它是额外的非聚集索引.

您正在从表中删除240行.

这相当于2640个索引行,其中240个包括表中的所有字段.

根据它们的宽度和所包含的字段数量,这可能等同于您所看到的所有额外读取活动.

非聚集索引行肯定不会在磁盘上组合在一起,这会增加延迟.


n8w*_*wrl 1

在解决了许多 SQL 性能问题后,我处理此类问题的标准操作程序是:

  1. 备份数据
  2. 删除相关表上的索引之一
  3. 测量操作
  4. 恢复数据库
  5. 重复#2,直到#3 显示出巨大的变化。这很可能就是你的罪魁祸首。