在SQL Server中删除240行11秒钟

我正在运行删除语句:

DELETE FROM TransactionEntries
WHERE SessionGUID = @SessionGUID

删除的实际执行计划是:

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

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

表格上没有触发器。

该操作需要:

  • 时长:11821 ms
  • CPU:297
  • 阅读:14340
  • 写作:1707
  • 该表包含11个索引:

  • 1聚集索引( SessionGUID
  • 1个唯一(主键)索引
  • 9个其他非唯一的非聚集索引
  • 我怎样才能找出为什么这个delete操作正在执行14,340读取,并需要11秒?

  • Avg. Disk Read Queue Length Avg. Disk Read Queue Length达到0.8
  • Avg. Disk sec/Read Avg. Disk sec/Read从不超过4ms
  • Avg. Disk Write Queue Length Avg. Disk Write Queue Length达到0.04
  • Avg. Disk sec/Write 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)
    

    每行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
    

    我整理了TransactionEntries17

    DBCC INDEXDEFRAG (0, 'TransactionEntries', 'TransactionEntries17')
    

    因为INDEXDEFRAG是一个“在线操作”(即它只保存IS Intent共享锁)。 然后我会手动对其他人进行碎片整理,直到业务部门称之为系统已经死亡 - 他们转而在纸上做所有事情。

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


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

    您正在删除表格中的240行。

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

    取决于它们的宽度以及包含的字段数量,这可能等同于您所看到的所有额外阅读活动。

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


    我认为索引可能是最可能的罪魁祸首,但我想抛出另一种可能性。 你提到没有触发器,但是有没有与这个表有外键关系的表? 必须检查它们以确保其中没有记录,并且如果打开了级联删除,那么还必须删除这些记录。


    在我遇到了很多SQL性能问题时,我的标准操作过程就是:

  • 备份数据
  • 删除有问题的表中的一个索引
  • 测量操作
  • 还原数据库
  • 重复w /#2,直到#3显示剧烈变化。 这可能是你的罪魁祸首。
  • 链接地址: http://www.djcxy.com/p/44005.html

    上一篇: 11 seconds to delete 240 rows in SQL Server

    下一篇: Why is SQLServerCE query performing a table scan and is it an issue?