Navicat 部落格

一些常見的 SQL 査詢錯誤 - 第 2 部分 2022 年 4 月 26 日,由 Robert Gravelle 撰寫

第 2 部分:非 SARGable 查詢條件

和大多數程式設計師一樣,資料庫開發人員或多或少傾向於撰寫直接翻譯指定請求的程式碼。大多數程式設計語言(包括 SQL)被設計為人們看得懂的,這也導致了一個問題。為什麼會有問題?所有程式設計語言都能比其他語言更快地執行某些作業。在關聯式資料庫中,查詢最佳化工具用於分析 SQL 查詢,並判斷稱為查詢計劃的高效執行機制。最佳化工具能為每個查詢產生一個或多個查詢計劃,每個查詢計劃代表一種可能的查詢執行方式。然後選取最有效的査詢計劃,並利用它來執行査詢。事實證明,模仿請求語言的 SQL 甚少是最有效的方法。

在常見的 SQL 查詢錯誤系列的這一部分中,我們將探討一個撰寫得不好的 SQL 陳述式的範例,並以提高效率的方式重寫它。

將索引欄傳遞至函式

在資料庫開發人員的程式碼中反復出現的一個錯誤是將索引欄傳遞至函式。為了舉例說明,我們會對這個資料表執行一個查詢,該資料表在 varchar customerName 欄上有一個索引:

customerName_index (95K)

當要求擷取名稱以字母「R」開頭的所有客戶時,可能傾向於使用 LEFT() 函式傳回 customerName 欄的第一個字元:

left_query (49K)

不幸的是,將索引的 customerName 欄傳遞至函式,查詢引擎必須評估資料表中每一列的結果!

SARGable 與非 SARGable 查詢

在關聯式資料庫中,有一個術語源自 Search ARGument ABLE 的縮寫,又名 SARGable。如果 DBMS 引擎可以利用索引來加速查詢的執行,則查詢中的條件(或述詞)被稱為 SARGable。另一方面,未能成為 SARGable 的查詢稱為非 SARGable 查詢。其效果類似於在沒有索引的書中搜尋特定術語,每次都從第一頁開始,而不是跳到索引中標識特定頁的清單。顯然,這對查詢時間有負面影響,因此查詢最佳化工具的其中一個步驟就是將此類條件轉化為 SARGable。

若要將上述條件轉化為 SARGable 條件,我們需要避免在索引欄上使用函式。要做到這一點,我們必須使用 Like 運算子,這個邏輯上對等(和 SARGable)的查詢來表達請求:

like_query (54K)

請注意,執行時間大大縮短。

結論

在關於常見的 SQL 查詢錯誤的第二部分中,我們了解了非 SARGable 查詢條件如何強制資料庫引擎評估資料表的每一列,導致查詢效能降低。解決方法是使用邏輯上對等(和 SARGable)的條件來表達請求,而不依賴於函式呼叫。

如果你想試用 Navicat 16 for MySQL,你可以在這裡下載 14 天的試用版。

Navicat 文章
頻道記錄
分享
部落格封存檔