首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 2008 nchar 與 nvarchar 索引差異:模糊查詢 LIKE '%關鍵字%' 單筆結果可用唯一非叢集索引

     編輯:關於SqlServer

冷門發現:定長 nchar + 唯一非叢集索引 + 單筆結果 = LIKE '%xxx%' 走索引

一般認知:`LIKE '%關鍵字%'` **前置萬用字元必定掃描**。但在 SQL Server 2008 實測發現特例:

觸發條件 (同時滿足)

  1. 欄位型別:**定長 `CHAR` / `NCHAR`** (非 `VARCHAR`/`NVARCHAR`)。
  2. 索引:**非叢集 + 唯一** (`UNIQUE NONCLUSTERED`)。
  3. 查詢結果:**預估/實際僅 1 筆** (或加 `AND` 其它條件後仍為 1 筆)。

實測案例

CREATE TABLE Movie (
    MovieID INT IDENTITY PRIMARY KEY,
    MName NCHAR(50) NOT NULL  -- 定長
);
CREATE UNIQUE NONCLUSTERED INDEX IX_Movie_MName ON Movie (MName);

-- 單筆結果
SELECT * FROM Movie WHERE MName LIKE N'%午夜%';           -- 走索引 Seek
SELECT * FROM Movie WHERE MName LIKE N'%午夜%' AND MName LIKE N'%鈴%'; -- 仍走索引 (結果 1 筆)

-- 多筆結果或可變長度欄位
SELECT * FROM Movie WHERE MName LIKE N'%午夜%';           -- 掃描 (若預估 >1 筆)
-- 若 MName 改為 NVARCHAR(50),同樣條件**不走索引**

可能原因推測

  • 定長欄位在索引葉層**固定位移**,唯一索引保證鍵值唯一,優化器對「單筆結果」的模糊查詢嘗試 **索引 Seek + 殘留謂詞** 而非掃描。
  • 可變長度欄位需讀取長度資訊、儲存格式不同,優化器未實作相同最佳化。
  • 此行為**非文件化、非標準、版本相關**,**不可作為設計依賴**,僅供學術探討。

正統解法:全文檢索 / 字首索引 / n-gram

方案適用場景優點缺點
全文檢索自然語言、詞幹、近似、同義詞功能最強、支援語意維護複雜、需獨立服務 (2008 整合)
字首索引 (Computed Column + Index)固定前綴查詢 `LIKE '關鍵字%'`標準索引 Seek、效能穩定不支援中間/尾部模糊
n-gram / Trigram 索引表任意位置模糊、自動完成通用、可排序儲存膨脹、寫入放大
Elasticsearch / Solr 外部引擎大規模、高併發、複雜查詢專業搜尋功能架構複雜、資料同步延遲

結語

`NCHAR + UNIQUE NONCLUSTERED + 單筆結果` 能讓 `LIKE '%xxx%'` 走索引,**是優化器的特例最佳化,非標準行為**。生產系統**請用全文檢索、字首索引或外部搜尋引擎**解決模糊查詢效能問題,切勿仰賴此不可文件化特性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved