LIKE 操作符是 SQL 模糊匹配的核心,配合通配符 %(任意長度字符)和 _(單個字符)可實現前綴、後綴、包含、定長模式查詢。本文聚焦數字類型字段的隱式轉換陷阱、索引利用條件與多條件組合寫法。
-- 前綴匹配(最常用,可用索引)
SELECT * FROM users WHERE phone LIKE '138%';
-- 後綴匹配(不可用索引)
SELECT * FROM users WHERE phone LIKE '%1234';
-- 包含匹配(不可用索引)
SELECT * FROM users WHERE realname LIKE '%李%';
-- 定長單字符匹配
SELECT * FROM users WHERE id_card LIKE '110101____________3X'; -- 18位身份證
當字段類型為數值型(INT、BIGINT、DECIMAL),LIKE '123%' 會觸發隱式類型轉換:MySQL 將數值轉為字符串再匹配,導致無法使用索引,全表掃描。
-- card_id 為 BIGINT
SELECT * FROM users WHERE card_id LIKE '4%'; -- 全表掃描!
-- 1. 顯式轉字符串(MySQL 8.0+ 支持函數索引可優化)
SELECT * FROM users WHERE CAST(card_id AS CHAR) LIKE '4%';
-- 2. 數值範圍代替(最優,利用索引)
-- 4 開頭的 18 位身份證:400000000000000000 到 499999999999999999
SELECT * FROM users WHERE card_id BETWEEN 400000000000000000 AND 499999999999999999;
-- 3. 應用層轉字符串存儲(如需頻繁前綴查詢,冗余字符串列 + 索引)
-- AND 組合:姓名包含"李" 且 身份證以"4"開頭
SELECT * FROM users
WHERE realname LIKE '%李%'
AND card_id BETWEEN 400000000000000000 AND 499999999999999999;
-- OR 組合:姓名包含"李" 或 "張"
SELECT * FROM users
WHERE realname LIKE '%李%' OR realname LIKE '%張%';
-- 複雜邏輯:(姓名含"李" AND 身份證4開頭) OR (姓名含"王" AND 手機138開頭)
SELECT * FROM users
WHERE (realname LIKE '%李%' AND card_id BETWEEN 400000000000000000 AND 499999999999999999)
OR (realname LIKE '%王%' AND phone LIKE '138%');
LIKE '%abc'、LIKE '%abc%' 無法用索引,全表掃描。INDEX idx_name_prefix (name(10)),LIKE 'abc%' 可用前綴索引。SELECT id, name FROM t WHERE name LIKE 'abc%' 若 INDEX (name, id) 可覆蓋,避免回表。FULLTEXT INDEX + MATCH() AGAINST(),替代 LIKE '%word%'。BETWEEN/>= <=。| 數據庫 | 大小寫敏感 | 轉義字符 | 備註 |
|---|---|---|---|
| MySQL | 默認不敏感(校對規則決定) | \ | LIKE BINARY 強制敏感 |
| PostgreSQL | 敏感 | \ | ILIKE 不敏感 |
| SQL Server | 默認不敏感 | [] 或 自定義 | PATINDEX 返回位置 |
| Oracle | 敏感 | \ | LIKE ... ESCAPE '\' |
LIKE 是模糊查詢利器,但數值字段禁用 LIKE、避免前導 %、善用範圍查詢替代、前綴索引/覆蓋索引/全文索引 是性能優化三板斧。多條件組合時注意括號優先級,EXPLAIN 驗證執行計劃,確保命中預期索引。