SQL Server 效能調校之二:看懂 Index Seek、Scan 與 Key Loop

更新 發佈閱讀 6 分鐘

在上一篇中,建立了閱讀執行計畫的「方向感」,學會透過箭頭粗細找出塞車路段。順著箭頭一路往右追溯到最源頭,就會看到 SQL Server 是如何進入資料庫「拿資料」,這一步至關重要,因為資料庫系統最大的效能瓶頸往往在於磁碟 I/O(資料讀寫),是在「精準尋找」還是在「盲目翻找」,決定了這個查詢是只要 0.1 秒,還是要跑 10 分鐘。

在執行計畫的最右側,最常看見的資料存取運算子有這幾種:

1.理想的境界:Index Seek

vocus|新世代的創作平台


  • 白話比喻: 就像查字典時,利用部首或注音索引,直接翻到你要的那一頁。
  • 背後意義: 這是效能最好的存取方式。代表 SQL Server 完美利用了 B-Tree 索引結構,精確定位到符合 WHERE 條件的資料列。看到這個圖示通常代表你的索引設計順利發揮了作用。

2.尷尬的中間地帶:Index Scan

vocus|新世代的創作平台


  • 白話比喻: 不用翻整本字典,但把字典的「整個附錄/整個目錄」從頭到尾看了一遍。
  • 背後意義: 看到 "Index" 這個字或許會覺得令人安心,但請注意後面的 "Scan"。這代表查詢條件無法讓 SQL Server 縮小搜尋範圍,只好把整個索引從頭到尾掃了一遍。
  • 優化建議:
    • 改善查詢條件(避免索引失效): 這是最常見的「索引殺手」,例如在欄位上套函數(如 WHERE YEAR(created_at) = 2026),或發生型別隱含轉換(字串比對數字欄位),可以改成對索引友善的寫法,例如:WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01',讓 SQL Server 能切換回 Index Seek。
    • 建立或調整 Composite Index(複合索引): 把常常一起出現在 WHEREORDER BY 的欄位組合進同一個索引,且要注意欄位順序。
    • 減少回傳欄位: 盡量避免 SELECT *,只取真正需要的欄位,有助於讓 Optimizer 選擇更精準的索引。

3.效能的紅燈:Table Scan / Clustered Index Scan


  • 白話比喻: 為了找書裡的一句話,從第一頁逐字逐句讀到最後一頁。
  • 背後意義: 這是最需要優先處理的狀況,代表完全沒有可用的索引,或查詢條件根本繞過了索引。SQL Server 必須把整張表掃描一遍,一筆一筆核對。
  • 優化建議:
    • 建立索引: 最直接的解法,可以先參考 Execution Plan 上方黃色字體的 Missing Index 提示來建立 Non-Clustered Index,這通常能立竿見影。
    • 檢查資料選擇性(Selectivity): 如果你的 WHERE 條件篩出來的資料佔了整張表的 20%–30% 以上,SQL Server 會認為「既然都要抓這麼多資料,不如直接掃整張表比較快」;此時加索引沒用,需要檢討的是查詢邏輯本身。
    • 更新統計資料: 執行 UPDATE STATISTICSsp_updatestats,有時候是資料庫的統計資訊太舊,導致 Optimizer 誤判,放著好好的索引不用跑去掃表。
    • 檢查 NOLOCK 或 Hint 干擾: 確認程式碼中是否有不必要的查詢提示(Hint)強制改變了 SQL Server 的預設行為。

4.隱藏的效能殺手:Key Lookup

vocus|新世代的創作平台


  • 白話比喻: 用目錄找到了頁碼,但發現那頁只有大綱,還得跑去另一本詳細版的手冊裡翻出完整內容。
  • 背後意義:有時候明明看到計畫裡有 Index Seek,查詢卻還是很慢?原因是現有索引只包含部分欄位。SQL Server 找到條件相符的資料列後,還要再「回表(回 Clustered Index)」去撈 SELECT 中缺乏的其他欄位,造成龐大的額外 I/O。
  • 優化建議:
    • 加上 INCLUDE 欄位(涵蓋索引 Covering Index): 這是最常見且有效的解法。把 SELECT 清單中非索引的欄位,加到 Non-Clustered Index 的 INCLUDE 裡,SQL Server 就不需要再回表了。
-- 原本會造成 Key Lookup 的索引
CREATE INDEX IX_Orders_CustomerId ON Orders (CustomerId);

-- 優化:加上 INCLUDE,把常查的欄位一起放進去
CREATE INDEX IX_Orders_CustomerId ON Orders (CustomerId)
INCLUDE (OrderDate, TotalAmount, Status);
    • 減少 SELECT 欄位: 如果 Key Lookup 次數極高,最快的解法是拿掉不必要的 SELECT 欄位,減少需要回表的負擔。
    • 合併重複的索引: 如果同一張表有多個相似的索引,各自 INCLUDE 不同的欄位,可以考慮合併成一個較完整的索引,降低維護成本與回表機率。

搞定了資料讀取的第一關,手上就有了最精簡的資料集;但在關聯式資料庫中,經常需要把多張表的資料拼湊在一起。這時候,SQL Server 會派誰上場呢?

在下一篇,我們將為你大解密三種截然不同,卻各有千秋的 Join 運算子!

留言
avatar-img
愷的大冒險 Kai's Adventure
6會員
16內容數
這裡記錄軟體工程相關工具、技能與學習的探索歷程,偶爾分享角落生物的美好日常,希望能透過文字與更多人交流,如果你對這些主題感興趣歡迎留言,讓我們一起碰撞出更多火花!
2026/05/06
在開發與維護資料庫的日常中,會遇到這樣的場景,一段 SQL 查詢平常跑得順順的,卻突然卡住,或者明明加了 WHERE 條件,資料庫卻慢到讓人想打電腦。
Thumbnail
2026/05/06
在開發與維護資料庫的日常中,會遇到這樣的場景,一段 SQL 查詢平常跑得順順的,卻突然卡住,或者明明加了 WHERE 條件,資料庫卻慢到讓人想打電腦。
Thumbnail
2026/05/05
承續上篇 OpenCode 搭配 OpenRouter 的踩坑紀錄:意外的模型扣費之謎,在今日反覆測試之後,終於找到了初步的解決之道。
Thumbnail
2026/05/05
承續上篇 OpenCode 搭配 OpenRouter 的踩坑紀錄:意外的模型扣費之謎,在今日反覆測試之後,終於找到了初步的解決之道。
Thumbnail
2026/05/04
今天在開發時,遇到了一個有趣但也讓人有點困擾的狀況。我目前的開發環境是使用 OpenCode 搭配 OpenRouter,主模型則是透過 OpenRouter BYOK (Bring Your Own Key) 綁定 Google AI Studio API Key 的 Google Gemini
Thumbnail
2026/05/04
今天在開發時,遇到了一個有趣但也讓人有點困擾的狀況。我目前的開發環境是使用 OpenCode 搭配 OpenRouter,主模型則是透過 OpenRouter BYOK (Bring Your Own Key) 綁定 Google AI Studio API Key 的 Google Gemini
Thumbnail
看更多
你可能也想看
Thumbnail
※ 什麼是ORDER BY? 可以讓SELECT出來的結果,根據你想要的方式排序。簡單說,用於對查詢結果進行排序。 ※ 語法: SELECT select_list FROM table_name ORDER BY column1 [ASC|DESC], column2 [ASC|DESC]
Thumbnail
※ 什麼是ORDER BY? 可以讓SELECT出來的結果,根據你想要的方式排序。簡單說,用於對查詢結果進行排序。 ※ 語法: SELECT select_list FROM table_name ORDER BY column1 [ASC|DESC], column2 [ASC|DESC]
Thumbnail
在進行SQL查詢邏輯更改時,需要適當地使用SubQuery和join來達到新的排序需求。本文將介紹原本的撈取邏輯、需求以及如何使用SubQuery來解決新的排序需求。
Thumbnail
在進行SQL查詢邏輯更改時,需要適當地使用SubQuery和join來達到新的排序需求。本文將介紹原本的撈取邏輯、需求以及如何使用SubQuery來解決新的排序需求。
Thumbnail
本篇文章是作者自學 SQL 的筆記,詳述資料庫中的四種主要語言類別:DDL、DML、TCL 及 DCL,每類別對應的功能與常見操作一一列舉,並深入探討交易的特性及其 ACID 原則。此外,文章還解釋了資料庫的正規化及反正規化的必要性,對於學習 SQL 的讀者有很大的幫助。
Thumbnail
本篇文章是作者自學 SQL 的筆記,詳述資料庫中的四種主要語言類別:DDL、DML、TCL 及 DCL,每類別對應的功能與常見操作一一列舉,並深入探討交易的特性及其 ACID 原則。此外,文章還解釋了資料庫的正規化及反正規化的必要性,對於學習 SQL 的讀者有很大的幫助。
Thumbnail
5 月,方格創作島正式開島。這是一趟 28 天的創作旅程。活動期間,每週都會有新的任務地圖與陪跑計畫,從最簡單的帳號使用、沙龍建立,到帶著你從一句話、一張照片開始,一步一步找到屬於自己的創作節奏。不需要長篇大論,不需要完美的文筆,只需要帶上你今天的日常,就可以出發。征服創作島,抱回靈感與大獎!
Thumbnail
5 月,方格創作島正式開島。這是一趟 28 天的創作旅程。活動期間,每週都會有新的任務地圖與陪跑計畫,從最簡單的帳號使用、沙龍建立,到帶著你從一句話、一張照片開始,一步一步找到屬於自己的創作節奏。不需要長篇大論,不需要完美的文筆,只需要帶上你今天的日常,就可以出發。征服創作島,抱回靈感與大獎!
Thumbnail
見諸參與鄧伯宸口述,鄧湘庭於〈那個大霧的時代〉記述父親回憶,鄧伯宸因故遭受牽連,而案件核心的三人,在鄧伯宸記憶裡:「成立了成大共產黨,他們製作了五星徽章,印刷共產黨宣言——刻鋼板的——他們收集中共空飄的傳單,以及中國共產黨中央委員會有關文化大革命決議文的英文打字稿,另外還有手槍子彈十發。」
Thumbnail
見諸參與鄧伯宸口述,鄧湘庭於〈那個大霧的時代〉記述父親回憶,鄧伯宸因故遭受牽連,而案件核心的三人,在鄧伯宸記憶裡:「成立了成大共產黨,他們製作了五星徽章,印刷共產黨宣言——刻鋼板的——他們收集中共空飄的傳單,以及中國共產黨中央委員會有關文化大革命決議文的英文打字稿,另外還有手槍子彈十發。」
Thumbnail
當時間變少之後,看戲反而變得更加重要——這是在成為母親之後,我第一次誠實地面對這一件事:我沒有那麼多的晚上,可以任性地留給自己了。看戲不再只是「今天有沒有空」,而是牽動整個週末的結構,誰應該照顧孩子,我該在什麼時間回到家,隔天還有沒有精神帶小孩⋯⋯於是,我不得不學會一件以前並不擅長的事:挑選。
Thumbnail
當時間變少之後,看戲反而變得更加重要——這是在成為母親之後,我第一次誠實地面對這一件事:我沒有那麼多的晚上,可以任性地留給自己了。看戲不再只是「今天有沒有空」,而是牽動整個週末的結構,誰應該照顧孩子,我該在什麼時間回到家,隔天還有沒有精神帶小孩⋯⋯於是,我不得不學會一件以前並不擅長的事:挑選。
Thumbnail
當代名導基里爾.賽勒布倫尼科夫身兼電影、劇場與歌劇導演,其作品流動著強烈的反叛與詩意。在俄烏戰爭爆發後,他持續以創作回應專制體制的壓迫。《傳奇:帕拉贊諾夫的十段殘篇》致敬蘇聯電影大師帕拉贊諾夫。本文作者透過媒介本質的分析,解構賽勒布倫尼科夫如何利用影劇雙棲的特質,在荒謬世道中尋找藝術的「生存之道」。
Thumbnail
當代名導基里爾.賽勒布倫尼科夫身兼電影、劇場與歌劇導演,其作品流動著強烈的反叛與詩意。在俄烏戰爭爆發後,他持續以創作回應專制體制的壓迫。《傳奇:帕拉贊諾夫的十段殘篇》致敬蘇聯電影大師帕拉贊諾夫。本文作者透過媒介本質的分析,解構賽勒布倫尼科夫如何利用影劇雙棲的特質,在荒謬世道中尋找藝術的「生存之道」。
Thumbnail
※ 語法 SELECT select_list FROM table_name​ ※ 解析順序 From:從哪裡拿? SELECT:要 "拿什麼" 資料? ※ 使用場景: Single column(單一欄位): Multiple column(多個欄位): All colu
Thumbnail
※ 語法 SELECT select_list FROM table_name​ ※ 解析順序 From:從哪裡拿? SELECT:要 "拿什麼" 資料? ※ 使用場景: Single column(單一欄位): Multiple column(多個欄位): All colu
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News