哪些SQL字符串函数适合做模糊查询优化?

阿枫酱_4643

阿枫酱_4643

2026-09-14

498人浏览

原创

instr在oracle中替代like '%keyword%'可提升性能近10倍,因其单次扫描定位优于like逐字符回溯;但不走索引,仅比全表扫描的like更轻量,真正索引优化需前缀匹配或函数索引。

哪些sql字符串函数适合做模糊查询优化?

Oracle 用 INSTR 替代 LIKE '%keyword%'

直接结论:INSTR 在 Oracle 中对中间匹配('%keyword%')的性能明显优于 LIKE,尤其在千万级表上实测快近 10 倍。它不依赖索引,但只做一次扫描定位,避免了 LIKE 对每个字符逐位回溯匹配的开销。

常见错误是以为 INSTR 能走索引——它不能,但它比全表扫 LIKE 更轻量。真正要走索引,必须用前缀匹配(LIKE 'keyword%')或函数索引(如 CREATE INDEX idx_title_upper ON t(UPPER(title)))。

使用要点:

  • INSTR(title, '手册') > 0 等价于 title LIKE '%手册%',但执行更快
  • 起始位置和出现次数参数慎用:省略时默认从头找第一次;传负数会从右往左查,但多数模糊场景不需要
  • 返回 0 表示未找到,注意 NULL 字段参与时结果仍为 0(不是 NULL),逻辑上等同于 NOT LIKE

MySQL 优先选 LOCATEINSTR,别用 FIND_IN_SET

LOCATE('kw', col)INSTR(col, 'kw') 功能一致(后者是前者的别名),都返回子串首次出现位置,0 表示不存在。它们比 LIKE '%kw%' 略快,因为跳过通配符解析开销,且 MySQL 优化器对这类函数更友好。

FIND_IN_SET 完全不是为通用模糊查询设计的:它要求字段值是逗号分隔的枚举字符串(如 'a,b,c'),且只匹配完整项。拿它查含子串的普通文本,结果一定为空或误判。

关键区别:

Agent Git Oracle
Agent Git Oracle

高级仓库分析与重构指南。基于AI推理识别技术债务与架构反模式。

下载
  • LOCATE('359950439_', sys_pid) > 0 → 正确,查子串存在性
  • FIND_IN_SET('359950439_', sys_pid) → 错误,除非 sys_pid 是类似 '123,359950439_,456' 的格式
  • 所有函数都不支持索引加速中间匹配,但 LOCATE/INSTR 的 CPU 开销更低

SQL Server 用 CHARINDEX,但得避开 LIKE 开头带 % 的写法

CHARINDEX('kw', col) > 0col LIKE '%kw%' 语义相同,但前者在执行计划中更容易被优化器识别为“简单存在判断”,尤其当字段有非空约束、统计信息较新时,有时能触发更紧凑的扫描路径。

真正卡性能的是 LIKE 自身的通配符位置:LIKE '%kw'(后缀匹配)和 LIKE '%kw%'(中间匹配)必然全表扫描;只有 LIKE 'kw%' 才可能走索引——前提是索引存在、选择性够高,且没被隐式转换干扰(比如字段是 VARCHAR,而参数是 NVARCHAR)。

实操提醒:

  • EXPLAIN(或 SQL Server 的执行计划)确认 typeindexrange,而不是 ALL
  • 避免写成 WHERE CHARINDEX(@kw, col) > 0 后又在应用层拼 @kw = '%' + @input + '%'——这会让函数失效,退化成 LIKE 语义
  • 如果必须查后缀,MySQL 8.0+ 可建反向索引:CREATE INDEX idx_name_rev ON t((REVERSE(name))),再查 REVERSE(name) LIKE REVERSE('abc') + '%'

跨数据库统一写法难,但可规避最大陷阱

没有哪个函数能在所有数据库里既语法一致又性能等效。INSTR 在 Oracle/MySQL 都可用,但 PostgreSQL 不支持;POSITION 是 SQL 标准函数,MySQL/PostgreSQL 支持,SQL Server 不认;CHARINDEX 是 SQL Server 专属。

最该守住的底线是:别让模糊条件变成全表扫描的开关。百万级以上数据,LIKE '%kw%' 就是性能红灯,不管换什么函数,只要逻辑还是“任意位置包含”,就只是把慢从 5 秒压到 3 秒,而非解决根本问题。

容易被忽略的点:

  • 中文字段要核对排序规则(COLLATION),utf8mb4_0900_as_csutf8mb4_unicode_ci 对“张/張”匹配结果不同
  • 搜真实含 %_ 的内容,必须用 ESCAPE,比如 WHERE comment LIKE '%10!%' ESCAPE '!'
  • 真正需要“含关键词”语义的场景,该上全文索引(MATCH AGAINSTtsvector)或 Elasticsearch,而不是在 LIKE 和字符串函数之间反复调优

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

3723

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

791

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

949

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5501

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2483

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5500

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

7141

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

970

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

852

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程