簡體   English   中英

SQL Server 2012:一個查詢中的SELECT和UPDATE會降低性能

[英]SQL Server 2012 : SELECT and UPDATE in one query slow performance

我正在運行SQL Server 2012,這一查詢正在破壞我的數據庫性能。

我的文本消息提供程序不支持預定的文本消息,因此我有一個文本消息引擎,該引擎從數據庫中提取消息並在預定的時間發送它們。 我將這個查詢放在一起可以從數據庫中獲取消息,還可以更改它們的狀態,以免再次被拾取。

該查詢工作正常,這僅導致CPU上的等待時間,特別是因為它每隔一秒鍾運行一次。 我安裝了一個數據庫性能軟件,它說此查詢占實例執行時間的92%。 該軟件還表示,每執行一次就執行347,267個邏輯讀取。

關於如何使此效果更好的任何想法?

我應該選擇一個臨時表並在返回結果之前更新這些結果嗎?

這是當前查詢:

    UPDATE TOP (30) dbo.Outgoing
    SET Status = 2
    OUTPUT INSERTED.OutgoingID, INSERTED.[Message], n.PhoneNumber, c.OptInStatus
    FROM dbo.Outgoing o
    JOIN Numbers n on n.NumberID = o.NumberID
    LEFT JOIN Contacts c on c.ContactID = o.ContactID
    WHERE Scheduled <= GETUTCDATE() AND SmsId IS NULL AND Status = 1

這是執行計划 執行計划

此查詢涉及三個表:去電,電話號碼和聯系方式

發送是該查詢處理的主表。 現在只有兩個索引,一個是OutgoingID [PK,bigint,not null]上的群集主鍵索引,另一個是SmsId [varchar(255),null]上的非群集,非唯一索引,它是從在系統中成功接收到消息后,我們的文本消息提供者。 狀態列只是一個整數列,它與幾種不同的狀態(計划的,已排隊的,已發送的,失敗的,等等)相關

數字只是一個簡單的表,我們在其中存儲唯一的手機號碼,該號碼的某些不同格式以及一些識別客戶的基本信息,例如名字,運營商等。它在NumberID [bigint]上只有一個聚集的主鍵索引。 PhoneNumber列只是一個varchar(15)。

聯系人表僅將個人(電話號碼)連接到我們的一位商人,並保持該號碼的選擇狀態以及與客戶/商人關系有關的其他信息。 與該查詢相關的唯一列是OptInStatus [位,不為null]和ContactID [PK,bigint,不為null]

-更新-

在Outgoing表上使用列(Scheduled,SmsId,Status)列添加了非聚集索引,這似乎將執行時間從2秒以上減少到了毫秒。 我明天將使用性能監控軟件進行檢查,以了解其改進情況。 謝謝大家到目前為止的幫助!

正如一些評論者已經指出的那樣,您需要在dbo.Outgoing表上dbo.Outgoing一個新索引。 服務器正在努力尋找要更新/輸出的行。 這很可能是問題所在:

WHERE Scheduled <= GETUTCDATE() AND SmsId IS NULL AND Status = 1

為了提高性能,您應該在dbo.Outgoing上創建這些索引所在的位置。 這將使Sql Server更容易找到正確的行。 另一方面,由於將有一個新索引在更新時需要注意,因此它將為實際更新創建更多工作。

在進行此操作時,縮短SmsId列可能是一個好主意,除非您實際需要將其長度設置為255個字符。 最好在創建索引之前。

正如你可能想具有用於是傳出和那些outgone消息單獨的表的替代解決方案。 那么你也能:

  • 從插入所有記錄OutgoingOutgone
  • 像您當前正在執行的那樣,使用output子句從Outgoing刪除所有記錄。

確保insertdelete操作是在一個事務中完成的,否則您很快就會在數據庫中出現奇怪的不一致之處。

這只是在CPU上引起等待時間,特別是因為它每隔一秒運行一次。

擺脫TOP 30並使其運行的頻率要比每隔一秒鍾一次(可能每兩或三分鍾一次)少得多。

您可以啟用sql服務器的最大並行度,以加快處理速度

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM