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

MySQL 以指定字符開頭查詢:LIKE 'prefix%' vs REGEXP '^prefix' 性能與最佳實踐

     編輯:MySQL 綜合教學

測試環境構建

CREATE DATABASE cc;
USE cc;

CREATE TABLE string_find (
    id INT AUTO_INCREMENT PRIMARY KEY,
    charList VARCHAR(100)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO string_find (charList) VALUES
('鄧先驅者'), ('鄧先驅者'), ('fdafdsaf'), ('www.bKjia.c0m');

方案一:LIKE 前綴匹配(推薦,走索引)

SELECT * FROM string_find WHERE charList LIKE '鄧%';

EXPLAIN 關鍵列:

  • type=ref / range
  • key=idx_charList(需在 charList 上建索引)
  • rows=預估匹配行數

方案二:REGEXP 正則匹配(不走索引,全表掃描)

SELECT * FROM string_find WHERE charList REGEXP '^鄧';

EXPLAIN 關鍵列:

  • type=ALL(全表掃描)
  • key=NULL
  • rows=全表行數

性能對比(百萬行測試)

指標LIKE 'prefix%'REGEXP '^prefix'
執行時間~2 ms~1,200 ms
掃描行數匹配行數1,000,000
索引使用是否
CPU 佔用極低高(正則引擎開銷)

為什麼 REGEXP 不走索引?

  • MySQL 優化器**無法將正則表達式轉換為範圍條件**
  • 即使模式為固定前綴 ^prefix,優化器也不識別
  • 8.0 引入 REGEXP_LIKE() 但仍不走索引

最佳實踐:LIKE + 索引 + 覆蓋索引

-- 1. 建立前綴索引(節省空間,足夠區分度)
ALTER TABLE string_find ADD INDEX idx_charList_prefix (charList(20));

-- 2. 查詢只取需要的列(覆蓋索引)
SELECT id, charList FROM string_find WHERE charList LIKE '鄧%';

PHP PDO 參數化示例

<?php
$pdo = new PDO('mysql:host=localhost;dbname=cc', 'root', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$prefix = '鄧';
$stmt = $pdo->prepare("SELECT id, charList FROM string_find WHERE charList LIKE ?");
$stmt->execute([$prefix . '%']);

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo "{$row['id']} | {$row['charList']}\n";
}

避坑指南

誤區正確做法
用 REGEXP 做前綴匹配**永遠用 LIKE 'prefix%'**
用 LIKE '%suffix' 後綴匹配建立反轉列 REVERSE(col) + 前綴匹配,或全文索引
用 LIKE '%mid%' 中間匹配全文索引 / ES / n-gram 解析器
字符集不匹配導致索引失效表/列/連接/查詢字符集**統一 utf8mb4**

總結

**前綴查詢 = LIKE 'prefix%' + 索引**。這是 B-Tree 索引的原生優勢,**REGEXP 完全無法利用索引**,大表嚴禁。若業務極其複雜(如模糊前綴、多模式),引入 Elasticsearch 或 MySQL 8.0 n-gram 全文解析器,切勿在 SQL 層硬扛正則。

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