缺乏索引對支持大型生產數據庫的影響
情況如下:幾個月前,我以支持的身份在一家新公司開始工作。我的部分職責將涉及在生產環境中執行查詢以幫助診斷應用程序問題。我在第一天就獲得了生產數據庫訪問權限(只讀)。我有點擔心這個,但克服了它。然後我開始調查一個問題。最大的表之一是無處不在的訂單表。我必須過濾’CustomerField’(字元串數據)並加入外鍵。現在我查看了架構,甚至沒有索引“CustomerField”。事實上,整個數據庫幾乎沒有任何索引。執行此查詢和其他類似查詢對性能有何影響?感覺不對,我應該有多擔心?
通常,最好對伺服器上通常執行的查詢或需要以最高性能執行的查詢的謂詞(、、和子句)中
JOIN
的WHERE
欄位進行索引。HAVING
大多數表至少應該有一個聚集索引,然後按照該索引中定義的欄位的順序儲存數據。這避免了堆的使用,堆的使用會隨著時間的推移而降低性能(特別是當它們不斷被修改時),並以無序的方式儲存數據。上一段中的每個陳述都有很多小警告 - 太多了,無法在一個答案中詳細介紹。並且索引在一張表上有自己的成本
INSERT
,因此一張表上的太多索引也會損害性能。但一般來說,了解並遵循這是一個很好的建議。正如 SMor 在評論中提到的那樣,如果沒有人抱怨,有時最好遵循一個如果它沒有壞就不要修復它的方法,但這並不意味著它不值得深入研究並理解你的性能影響可能是最嚴重的違規者,無論是在他們自己的呼叫堆棧的上下文中,還是在伺服器上更全域的上下文中,因為它們消耗資源。
最好的方法之一是利用以下一些工具,一些更聰明的 SQL-folk 已經免費提供了這些工具:
- First Responder Kit - 由 Brent Ozar 和前團隊製作,裡面有很多強大的程序可以幫助你找出最嚴重的罪犯。特別是
sp_BlitzCache
它會告訴你伺服器記憶體中最糟糕的查詢計劃。可以呼叫 with@SortOrder = 'cpu'
來獲取按 CPU 消耗排序的結果,或者@SortOrder = 'xpm'
獲取按每分鐘最頻繁執行的查詢排序的結果。此外sp_BlitzIndex
,還會為您提供最糟糕的索引情況(缺少索引、太多索引或寫入大量但未從大量讀取的無用索引)。套件中的其他程序提供了大量有用的資訊,但需要大量練習才能習慣使用。sp_PressureDetector
是另一個很棒的工具,它可以全面了解導致伺服器資源爭用的事物。它是由 Erik Darling 編寫的,他也是 First Responder Kit 的前貢獻者。- 最後,Adam Machanic
sp_WhoIsActive
是另一個很棒的工具,可以幫助您查看伺服器上目前正在執行的內容、這些查詢正在等待和/或被阻止的內容,以及它們執行了多長時間(以及其他有用的資訊 -例如執行使用者和機器)。當出現性能問題時,這是一個在緊要關頭執行的好工具。(前面提到的 Erik Darling 也是該工具最新版本的貢獻者)。前面提到的所有三個工具都非常適合練習並熟悉何時使用它們。但是為了特別研究特定的索引問題,我建議先
sp_BlitzIndex
看看它是否有任何與您的orders
表相關的建議。
正如 JD 提到的(或缺少)索引會對查詢級別的性能產生重大影響,這當然值得進一步調查。簡而言之,SQL 可以有效地使用索引越多,您的查詢就越好,SQL Server 要做的工作就越少,這意味著資源消耗越少。
這是一個令人難以置信的高級視圖,畢竟這是一個非常深奧的主題——微軟最近更新了他們的索引架構和 SQL Server 和 Azure SQL 的設計指南,非常值得一讀:
當然,現在您不能只將索引投入生產數據庫,但如果您有合適的開發/測試環境,那麼您可以通過查看特定查詢(之前和之後)的執行計劃來評估添加索引的影響掃描/搜尋運算符,讀取的行數等 - 但請記住,表索引可能會導致來自其他查詢的更新成本,這是一種平衡行為!