我正在運行SQL Server 2012,這一個查詢正在殺死我的數據庫性能。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 [位,不爲空]和使用ContactID [PK,BIGINT NOT NULL]
--UPDATE--
加上了一個非聚集索引帶有列(Scheduled,SmsId,Status)的Outgoing表,這似乎將執行時間從2秒減少到了毫秒。我會在明天檢查我的性能監視軟件,看看它是如何改進的。感謝大家迄今爲止的幫助!
查詢的執行計劃是什麼?這裏的表格模式是什麼?你在Numbers和Outgoing上有哪些索引? –
我猜你需要'(狀態,預定)'或可能'(狀態,預定,數字ID)'索引。 – RBarryYoung
沒有'ORDER BY',你的'TOP 30'是不安全的。如果超過30個符合您的標準的記錄,您可能不會更新您希望更新的30個記錄。 – alroc