簡體   English   中英

SQL語句 - 如何通過索引提高速度

[英]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的條件)必須建立索引。

同樣,作為拇指規則,我遵循以下標准:

  1. 必須為每個關鍵字段(主要或外部)編制索引
  2. 必須對我必須執行頻繁查找的每個date字段編制索引
  3. 雖然我避免使用它,但如果我需要對charvarchar字段執行頻繁搜索,我也會對它們進行索引

請注意,很容易陷入索引所有內容的誘惑。 不要這樣做。 小心並設計具有最佳成本 - 收益關系的索引。

我是MySQL用戶,我不知道如何在SQL服務器中執行此操作,但必須有一種方法來顯示查詢的執行計划(在MySQL中它explain select... )。 嘗試顯示執行計划,然后根據需要確定索引所需的字段。

暫無
暫無

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

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