[英]SQL Statement - How can Improve speed with indexing
我有一個腳本,必須查看超過250萬條記錄,以查找是否有未讀電子郵件的成員。 我想知道如何提高速度。 目前,運行腳本最多可能需要8秒鍾:
SELECT TOP(1) MemberMailID
FROM MemberMail
WHERE ToReadFlag = 0
AND ToMemberID = 102
AND ToDeletedFlag = 0
AND FromDeletedFlag = 0
AND OnHold = 0
AND ToArchivedFlag = 0
如何使用索引加快速度?
此索引可能會有所幫助,但請記住,沒有免費午餐(必須維護索引,因此這將影響您的插入/更新/刪除工作負載):
CREATE NONCLUSTERED INDEX unread_emails
ON dbo.MemberMail(ToMemberID)
INCLUDE (MemberMailID)
WHERE ToReadFlag = 0
AND ToDeletedFlag = 0
AND FromDeletedFlag = 0
AND OnHold = 0
AND ToArchivedFlag = 0;
現在您的查詢可以說:
SELECT TOP (1) MemberMailID
FROM dbo.MemberMail -- dbo prefix
WITH (INDEX (unread_emails)) -- in case you need to force, though you should not
WHERE ToMemberID = 102
AND ToReadFlag = 0
AND ToDeletedFlag = 0
AND FromDeletedFlag = 0
AND OnHold = 0
AND ToArchivedFlag = 0
ORDER BY ToMemberID; -- ORDER BY is important!
如果根據查詢更改其中某些標志的值,您可以嘗試將這些列添加到索引的鍵而不是過濾器,例如,假設您有時檢查OnHold = 0
,有時OnHold = 1
:
CREATE NONCLUSTERED INDEX unread_emails
ON dbo.MemberMail(ToMemberID, OnHold)
INCLUDE (MemberMailID)
WHERE ToReadFlag = 0
AND ToDeletedFlag = 0
AND FromDeletedFlag = 0
AND ToArchivedFlag = 0;
您可能還想嘗試在密鑰中使用MemberMailID
而不是INCLUDE
。 例如:
CREATE NONCLUSTERED INDEX unread_emails
ON dbo.MemberMail(ToMemberID, MemberMailID)
WHERE ToReadFlag = 0
AND ToDeletedFlag = 0
AND FromDeletedFlag = 0
AND OnHold = 0
AND ToArchivedFlag = 0;
這些差異可能與您的數據和使用模式無關,但您將能夠比我們能夠猜測的更容易地測試差異。
看起來像是過濾索引的一個很好的候選者。
過濾索引是優化的非聚簇索引,尤其適用於覆蓋從明確定義的數據子集中進行選擇的查詢。 它使用過濾謂詞來索引表中的一部分行。 與全表索引相比,精心設計的篩選索引可以提高查詢性能,降低索引維護成本並降低索引存儲成本。
這些方面的東西:
CREATE NONCLUSTERED INDEX IX_MemberMail_ToMemberId_Unread
ON dbo.MemberMail (ToMemberId ASC)
WHERE ToReadFlag = 0
AND ToDeletedFlag = 0
AND FromDeletedFlag = 0
AND OnHold = 0
AND ToArchivedFlag = 0;
通過SSMS中的(CTRL + M)獲取實際查詢計划 。 或者將您的查詢粘貼到SSMS中,右鍵單擊它,選擇在數據庫引擎優化顧問中分析查詢 ,您將看到需要添加的索引。 基本上,您需要復合+包含索引。
作為一個經驗法則, 每場在其上進行頻繁的過濾器( where
的條件)必須建立索引。
同樣,作為拇指規則,我遵循以下標准:
date
字段編制索引 char
或varchar
字段執行頻繁搜索,我也會對它們進行索引 請注意,很容易陷入索引所有內容的誘惑。 不要這樣做。 小心並設計具有最佳成本 - 收益關系的索引。
我是MySQL用戶,我不知道如何在SQL服務器中執行此操作,但必須有一種方法來顯示查詢的執行計划(在MySQL中它explain select...
)。 嘗試顯示執行計划,然后根據需要確定索引所需的字段。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.