能,但仅限前缀匹配(如'abc%')且字段无函数包裹;后缀、中缀匹配及函数处理均导致索引失效,需结合执行计划、统计信息和架构优化综合解决。
LIKE 在索引字段上能走索引吗?
能,但有严格前提:必须是前缀匹配,且不能有函数包裹字段。比如 where name like 'john%' 可以用到 name 字段上的 b-tree 索引;而 where name like '%ohn%' 或 where upper(name) like 'john%' 就完全无法走索引,只能全表扫描。
常见错误现象:EXPLAIN PLAN 显示 FULL TABLE SCAN,但 SQL 看起来“明明有索引”。这时候要检查通配符位置和是否对列做了隐式转换。
- 前缀匹配(
'abc%')→ 可走索引 - 后缀或中缀(
'%abc'、'%abc%')→ 不走索引 - 字段加了函数(
UPPER(col)、TRIM(col))→ 索引失效,除非建函数索引 - 绑定变量写成
LIKE :v1且传入值以 % 开头 → 同样不走索引,优化器无法预判范围
REGEXP_LIKE 为什么比 LIKE 慢那么多?
因为 REGEXP_LIKE 是逐行调用正则引擎解析的,每行都要做状态机匹配,开销远高于 LIKE 的简单字符比对。即使表达式看起来很轻量(比如 REGEXP_LIKE(col, '^A.*') ),它也绕不开正则编译+执行的固定成本。
使用场景上,别为了“写得短”就用 REGEXP_LIKE 替代 LIKE。只有真正需要正则能力时才用——比如校验邮箱格式、提取数字段、匹配多模式交替('(cat|dog|bird)')。
-
REGEXP_LIKE(col, '^[A-Z]{2}\d{6}$')→ 合理,LIKE 做不到 -
REGEXP_LIKE(col, '^ABC%')→ 错误,应改用LIKE 'ABC%' - 在 WHERE 中混用多个
REGEXP_LIKE→ 性能雪崩,尤其数据量 > 10k 行时响应明显变慢 - Oracle 12c+ 对简单正则有部分优化,但依然无法替代 LIKE 的索引友好性
模糊匹配性能差,先看执行计划再动代码
很多同学一看到慢就急着换函数或加 hint,其实第一步永远是 EXPLAIN PLAN FOR ... + SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)。真正卡点往往不是函数本身,而是缺失索引、统计信息过期、绑定变量窥探失败这些底层问题。
一个典型反例:某表 user_name 有索引,但 WHERE user_name LIKE 'Li%' 还是慢。查执行计划发现走了 INDEX RANGE SCAN,但返回 50 万行,最终 HASH JOIN 拖垮整体。这时加索引没用,该考虑加过滤条件或改用物化视图。
- 先跑
EXPLAIN PLAN,确认是否真走索引、返回行数预估是否合理 - 用
DBMS_STATS.GATHER_TABLE_STATS更新统计信息,避免优化器误判 - 检查绑定变量类型是否和字段一致(比如
VARCHAR2字段传CHAR绑定变量,可能触发隐式转换) - 若必须中缀搜索,考虑
CONTEXT索引 +CONTAINS,而不是硬扛REGEXP_LIKE
什么时候该放弃模糊匹配,换其他方案?
当模糊查询成为高频核心路径,且数据持续增长,靠改 SQL 函数基本没救。这时候就得跳出语法层面,从架构上拆解问题。
比如用户搜索姓名,要求支持“张*明”“李?华”,本质是前缀+通配组合。与其在数据库里硬算,不如把清洗后的关键词落进 CTXSYS.CONTEXT 索引,或导出到 Elasticsearch 做分词检索。PL/SQL 不是万能胶,它适合事务逻辑,不适合当搜索引擎用。
- 模糊查询 QPS > 50,且响应要求
- 需要支持拼音、同音字、错别字 →
LIKE和REGEXP_LIKE都无能为力 - 字段内容含大量空格、特殊符号、大小写混杂 → 先标准化再入库,比运行时处理更可靠
- 业务允许延迟:用物化视图预计算常用模糊组合,查表代替实时匹配
真正难的不是选 LIKE 还是 REGEXP_LIKE,而是判断这个模糊需求到底该不该放在数据库里解决。越早看清这点,越少在执行计划里反复横跳。











