Sql-Server

SQL Server 表上不可預測的單次插入性能

  • May 7, 2020

我繼承了一個有時表現出極差的單記錄插入性能的系統。

該表大約有 800 萬行,因此相對較大,但並非特別大。以下簡單的插入花費了 7 多分鐘,並在此過程中阻塞了整個系統:

  INSERT INTO dbo.Communication(comm_action,comm_channelid,...)  
  VALUES (N'Deskwork',11,...)

整體數據庫設計相當差。例如,儘管這個特定的表確實有一個聚集索引,但它也有 34 個其他索引,儘管它是一個具有大量插入/更新活動的 OLTP 系統。

我看不到任何觸發器,並且插入的性能在大多數情況下都相當不錯。好是一個相對的術語。

索引的數量真的可以解釋如此糟糕的性能嗎?在開始工作之前我可以採取什麼方法來證明這一點。

如果共識不是索引問題,我還可以研究其他領域嗎?

客戶對更改非常敏感,因此我需要證據才能做出任何更改。

我使用 SQL Sentry 來突出顯示阻塞,插入是顯示的第一個塊,然後是許多其他塊。

這實際上比只有另一個程序阻塞插入器更奇怪。我有一個程序 (51) 被程序 105 阻止。但是,當我檢查程序 105 是關於什麼時,沒有程序 105

我已經重複了幾次,每次都有不同的程序說它被阻塞了很長一段時間,但“阻塞器”並不真正存在。有誰知道為什麼sys.dm_exec_requests可以說某些東西被阻止了,但是同一個 DMV 說阻止程序實際上並不存在?

發生的情況是,我們在dm_exec_requests中獲得了阻塞會話 id 為 127 的行。但是,儘管dm_exec_sessions中有一個會話,但它表示它正在休眠,並且請求 DMV 中沒有等效的行。

儘管似乎沒有做任何請求,但我不清楚會話如何阻止某些內容 30 分鐘?

對於被阻止的請求,在我今天早上遇到的情況下,它正在等待一個LCK_M_S. 有任何想法嗎?

我懷疑這不是“插入需要 7 分鐘”的情況,而是“插入被阻止超過 6 分鐘”的情況。當插入正常執行,然後突然需要很長時間時,可能還有其他原因,SQL Server 不太可能突然被索引過多的大表淹沒。

我在這裡更詳細地處理了這一點,但本質上,您需要在此查詢執行時檢查系統 long。辨識session_id( SPID) 並檢查sys.dm_exec_requestsblocking_session_id我認為這很可能是問題所在;之後,檢查wait_typelast_wait_type。大多數情況下,對於像這樣的持續時間異常值,其中一列將幫助您找出原因。

有時,他們可能沒有活躍的查詢sys.dm_exec_requests——正如我在下面的評論中解釋的那樣,如果有人開始一個事務,對一個表做了一些語句,然後沒有送出就走開了,這是可能的。即使他們沒有主動執行查詢,您也可以看到該會話已鎖定哪些對象。

DECLARE @SPID INT = <blocking_session_id from your "hung" query>;

-- see the command they ran last (might be related, might not)
DBCC INPUTBUFFER(@SPID);

-- see what that session has locked
SELECT s.name, o.name
 FROM sys.dm_tran_session_transactions AS tst
 INNER JOIN sys.dm_tran_locks AS tl
 ON tst.transaction_id = tl.request_owner_id
 INNER JOIN sys.objects AS o
 ON tl.resource_associated_entity_id = o.[object_id]
 INNER JOIN sys.schemas AS s
 ON o.[schema_id] = s.[schema_id]
 WHERE tst.session_id = @SPID;

引用自:https://dba.stackexchange.com/questions/129302