【 80億資料500行的搜尋指令之求生術系列 】SQL Server 效能調校 (1)~(5)

更新 發佈閱讀 5 分鐘

80億資料500行的搜尋指令是在工作時遇過得真實場景,這個系列是我在工作實務中歸納出來的學習筆記,起初真的是頭大,找資料找到眼花撩亂,希望可以給需要的人一些頭緒,這系列目前暫定先寫到這裡囉,歡迎大家交流。

第一|Execution Plan 的閱讀方向與指標

打開執行計畫,掌握兩個核心法則:

  • 閱讀方向從右到左:最右邊是資料來源(表或索引),中間是各處理步驟,最左邊才是 SELECT 輸出。下次先看最右端,而非盯著 SELECT。
  • 箭頭粗細代表資料量:「粗進細出」是漏斗效應,代表浪費大量資源過濾資料,需從源頭篩選;「一路粗到底」則要問應用端是否真的需要這麼多筆。

第二|看懂 Index Seek、Scan 與 Key Lookup

資料庫最大的效能瓶頸在磁碟 I/O,「精準尋找」還是「盲目翻找」差距可達百倍。

  • Index Seek:最理想,利用 B-Tree 直接定位,如查字典靠索引翻到正確頁面。
  • Index Scan:有索引但整個掃一遍,常因欄位套函數、型別轉換等導致索引失效,需改寫條件或調整複合索引。
  • Table Scan / Clustered Index Scan:最差狀況,整張表逐筆掃描,優先建立索引或執行 UPDATE STATISTICS。
  • Key Lookup:找到資料後還要「回表」撈其他欄位,大量額外 I/O。解法是把常查欄位加入索引的 INCLUDE 清單,形成 Covering Index。

第三|三大 Join 運算子解密

Optimizer 會自動選擇,但看懂背後邏輯才能抓出問題。

  • Nested Loops:小表 Join 大表且有索引時效率極好;兩表都大又無索引時複雜度 O(N×M),效能急速惡化。
  • Hash Match:無索引大數據的最後防線,複雜度 O(N+M),但記憶體不足時會 Spill to TempDB(出現黃色警告),是必須優先解決的瓶頸。
  • Merge Join:兩表都已排序時效率最佳、記憶體需求最低;若資料未排序,SQL Server 會強加一個昂貴的 Sort,反而得不償失。

統計資料過舊會導致 Optimizer 猜錯資料量,選錯 Join 方式,執行 UPDATE STATISTICS 往往立竿見影。

第四|四個常見陷阱解析

  • Missing Index:篩選欄位沒有索引,導致全表掃描。執行計畫會出現綠色提示;建立時善用 INCLUDE 可同時消滅 Key Lookup。
  • Implicit Conversion:參數型別與欄位不符,SQL Server 悄悄轉換,Index Seek 退化為 Scan,只剩一個小黃警告 CONVERT_IMPLICIT 極易忽略。ORM 框架的 nvarchar/varchar 混用是最常見來源。
  • Spill to TempDB:Sort、Hash Match 等運算的工作記憶體不足,中間資料溢到硬碟。根本原因通常是統計資料過舊,建索引無法解決,要跑 UPDATE STATISTICS。
  • Residual Predicate:Index Seek 只用了部分鍵欄位定位,其餘條件逐列過濾,Rows Read 遠大於 Actual Rows 卻不易察覺。需點開節點屬性分辨 Seek Predicates 與 Predicates,調整複合索引欄位順序。

第五|除錯 SOP 四步驟

面對幾十上百節點的龐大執行計畫,核心心法:一次只動一個地方,永遠以數據驗證差異。

  • Step 1 擒賊先擒王:找 Cost % 最高的節點與最粗的箭頭,鎖定 1~2 個最差局部,不急著全域改寫。
  • Step 2 懸停健康檢查:看有無黃色驚嘆號、存取方式是 Seek 還是 Scan、有無伴隨 Key Lookup。
  • Step 3 戳破預估幻覺:比對 Estimated Rows 與 Actual Rows,落差大先跑 UPDATE STATISTICS,往往 Optimizer 就能自動選對計畫。
  • Step 4 單一變數驗證:改前用 SET STATISTICS IO ON 記錄基準,每次只改一件事,確認 Logical reads 下降才算真正有效。

Read More


留言
avatar-img
愷的大冒險 Kai's Adventure
6會員
17內容數
這裡記錄軟體工程相關工具、技能與學習的探索歷程,偶爾分享角落生物的美好日常,希望能透過文字與更多人交流,如果你對這些主題感興趣歡迎留言,讓我們一起碰撞出更多火花!
2026/05/11
經過前面四篇文章,能夠知道 Execution Plan 的四大核心:閱讀方向(粗細箭頭)、存取方式(Seek 與 Scan)、關聯策略(三大 Join)以及警告標誌(四大陷阱)。 然而當面對一張包含幾十個、甚至上百個節點的巨大執行計畫時,很容易感到不知所措;這時候需要的是一套系統化的除錯 SOP。
Thumbnail
2026/05/11
經過前面四篇文章,能夠知道 Execution Plan 的四大核心:閱讀方向(粗細箭頭)、存取方式(Seek 與 Scan)、關聯策略(三大 Join)以及警告標誌(四大陷阱)。 然而當面對一張包含幾十個、甚至上百個節點的巨大執行計畫時,很容易感到不知所措;這時候需要的是一套系統化的除錯 SOP。
Thumbnail
2026/05/10
在調校 SQL Server 查詢效能時,有些問題容易被忽略,卻也容易造成嚴重的效能退化:Missing Index、Implicit Conversion、Spill to TempDB、以及 Residual Predicate。整理這四種問題的成因、症狀與修正方式,並說明彼此之間容易混淆的關鍵
Thumbnail
2026/05/10
在調校 SQL Server 查詢效能時,有些問題容易被忽略,卻也容易造成嚴重的效能退化:Missing Index、Implicit Conversion、Spill to TempDB、以及 Residual Predicate。整理這四種問題的成因、症狀與修正方式,並說明彼此之間容易混淆的關鍵
Thumbnail
2026/05/09
延續上篇,當我們確保了資料存取的效率(消滅了不必要的 Scan 與 Key Lookup)後,接下來要面對的就是關聯式資料庫最核心的動作:將多張資料表結合在一起(Join)。
Thumbnail
2026/05/09
延續上篇,當我們確保了資料存取的效率(消滅了不必要的 Scan 與 Key Lookup)後,接下來要面對的就是關聯式資料庫最核心的動作:將多張資料表結合在一起(Join)。
Thumbnail
看更多
你可能也想看
Thumbnail
見諸參與鄧伯宸口述,鄧湘庭於〈那個大霧的時代〉記述父親回憶,鄧伯宸因故遭受牽連,而案件核心的三人,在鄧伯宸記憶裡:「成立了成大共產黨,他們製作了五星徽章,印刷共產黨宣言——刻鋼板的——他們收集中共空飄的傳單,以及中國共產黨中央委員會有關文化大革命決議文的英文打字稿,另外還有手槍子彈十發。」
Thumbnail
見諸參與鄧伯宸口述,鄧湘庭於〈那個大霧的時代〉記述父親回憶,鄧伯宸因故遭受牽連,而案件核心的三人,在鄧伯宸記憶裡:「成立了成大共產黨,他們製作了五星徽章,印刷共產黨宣言——刻鋼板的——他們收集中共空飄的傳單,以及中國共產黨中央委員會有關文化大革命決議文的英文打字稿,另外還有手槍子彈十發。」
Thumbnail
當時間變少之後,看戲反而變得更加重要——這是在成為母親之後,我第一次誠實地面對這一件事:我沒有那麼多的晚上,可以任性地留給自己了。看戲不再只是「今天有沒有空」,而是牽動整個週末的結構,誰應該照顧孩子,我該在什麼時間回到家,隔天還有沒有精神帶小孩⋯⋯於是,我不得不學會一件以前並不擅長的事:挑選。
Thumbnail
當時間變少之後,看戲反而變得更加重要——這是在成為母親之後,我第一次誠實地面對這一件事:我沒有那麼多的晚上,可以任性地留給自己了。看戲不再只是「今天有沒有空」,而是牽動整個週末的結構,誰應該照顧孩子,我該在什麼時間回到家,隔天還有沒有精神帶小孩⋯⋯於是,我不得不學會一件以前並不擅長的事:挑選。
Thumbnail
題目敘述 題目會給我們一張Cinema資料表,裡面分別有id、movie、description, rating 等欄位,其中id 是主鍵Primary Key。 要求我們列出所有推薦人ID為奇數,而且不無聊的電影,印出時依照電影rating評分從高到低降序排列。 Table: Cinema
Thumbnail
題目敘述 題目會給我們一張Cinema資料表,裡面分別有id、movie、description, rating 等欄位,其中id 是主鍵Primary Key。 要求我們列出所有推薦人ID為奇數,而且不無聊的電影,印出時依照電影rating評分從高到低降序排列。 Table: Cinema
Thumbnail
題目敘述 題目會給我們兩張資料表,第一張是Sales,第二張是Product。 第一張是Sales表格,裡面分別有sale_id、 product_id、year、quantity、price等欄位。其中(sale_id、 product_id)做為複合主鍵Primary key
Thumbnail
題目敘述 題目會給我們兩張資料表,第一張是Sales,第二張是Product。 第一張是Sales表格,裡面分別有sale_id、 product_id、year、quantity、price等欄位。其中(sale_id、 product_id)做為複合主鍵Primary key
Thumbnail
當代名導基里爾.賽勒布倫尼科夫身兼電影、劇場與歌劇導演,其作品流動著強烈的反叛與詩意。在俄烏戰爭爆發後,他持續以創作回應專制體制的壓迫。《傳奇:帕拉贊諾夫的十段殘篇》致敬蘇聯電影大師帕拉贊諾夫。本文作者透過媒介本質的分析,解構賽勒布倫尼科夫如何利用影劇雙棲的特質,在荒謬世道中尋找藝術的「生存之道」。
Thumbnail
當代名導基里爾.賽勒布倫尼科夫身兼電影、劇場與歌劇導演,其作品流動著強烈的反叛與詩意。在俄烏戰爭爆發後,他持續以創作回應專制體制的壓迫。《傳奇:帕拉贊諾夫的十段殘篇》致敬蘇聯電影大師帕拉贊諾夫。本文作者透過媒介本質的分析,解構賽勒布倫尼科夫如何利用影劇雙棲的特質,在荒謬世道中尋找藝術的「生存之道」。
Thumbnail
本文基於作者 20+ 場新創及全球科技公司的面試經驗,以及擔任面試官的實戰經驗,深度解析 SQL 技術面試的評估標準與準備策略,並提供 5 道經典題目解析,助你順利通過技術關卡!
Thumbnail
本文基於作者 20+ 場新創及全球科技公司的面試經驗,以及擔任面試官的實戰經驗,深度解析 SQL 技術面試的評估標準與準備策略,並提供 5 道經典題目解析,助你順利通過技術關卡!
Thumbnail
題目敘述 題目會給我們一張Customer資料表,裡面分別有id、name、referee_id 等欄位,其中id 是主鍵Primary Key。 要求我們列出所有推薦人ID referee_id不等於2的顧客,印出順序不拘。
Thumbnail
題目敘述 題目會給我們一張Customer資料表,裡面分別有id、name、referee_id 等欄位,其中id 是主鍵Primary Key。 要求我們列出所有推薦人ID referee_id不等於2的顧客,印出順序不拘。
Thumbnail
5 月,方格創作島正式開島。這是一趟 28 天的創作旅程。活動期間,每週都會有新的任務地圖與陪跑計畫,從最簡單的帳號使用、沙龍建立,到帶著你從一句話、一張照片開始,一步一步找到屬於自己的創作節奏。不需要長篇大論,不需要完美的文筆,只需要帶上你今天的日常,就可以出發。征服創作島,抱回靈感與大獎!
Thumbnail
5 月,方格創作島正式開島。這是一趟 28 天的創作旅程。活動期間,每週都會有新的任務地圖與陪跑計畫,從最簡單的帳號使用、沙龍建立,到帶著你從一句話、一張照片開始,一步一步找到屬於自己的創作節奏。不需要長篇大論,不需要完美的文筆,只需要帶上你今天的日常,就可以出發。征服創作島,抱回靈感與大獎!
Thumbnail
這篇文章主要是介紹了SQL查詢效能調校的方法,針對索引最佳化做了整理和分享,並提供了一些注意事項和建議。
Thumbnail
這篇文章主要是介紹了SQL查詢效能調校的方法,針對索引最佳化做了整理和分享,並提供了一些注意事項和建議。
Thumbnail
題目敘述 題目會給我們一張Courses資料表,裡面分別有student、class等欄位。其中(student, class) 是這張資料表的複合主鍵Primary key pair。 要求我們,以課程做分群,列出至少有五位同學的課程。 輸出的順序不拘。 Table: Courses
Thumbnail
題目敘述 題目會給我們一張Courses資料表,裡面分別有student、class等欄位。其中(student, class) 是這張資料表的複合主鍵Primary key pair。 要求我們,以課程做分群,列出至少有五位同學的課程。 輸出的順序不拘。 Table: Courses
Thumbnail
題目敘述 題目會給我們一張World資料表,裡面分別有name、 continent、area、population 、gdp等欄位,其中name 是主鍵Primary Key。 要求我們列出所有大型國家,大型國家的定義是 人口大於等於兩千五百萬人 或者 土地面積大於等於三百萬平方公里。 輸出順
Thumbnail
題目敘述 題目會給我們一張World資料表,裡面分別有name、 continent、area、population 、gdp等欄位,其中name 是主鍵Primary Key。 要求我們列出所有大型國家,大型國家的定義是 人口大於等於兩千五百萬人 或者 土地面積大於等於三百萬平方公里。 輸出順
Thumbnail
題目敘述 題目會給我們一張Activity資料表,裡面分別有user_id、 session_id、activity_date 、activity_type等欄位。 要求我們列出所有過去30天的活躍使用者。 活躍使用者的定義為2019-07-27包含這天,往前三十天的區間內,至少有過一次活動紀錄
Thumbnail
題目敘述 題目會給我們一張Activity資料表,裡面分別有user_id、 session_id、activity_date 、activity_type等欄位。 要求我們列出所有過去30天的活躍使用者。 活躍使用者的定義為2019-07-27包含這天,往前三十天的區間內,至少有過一次活動紀錄
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News