如何优化SQL中带有LIKE模糊匹配的分组查询

来源:中国站长站作者:辉辉头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何优化SQL中带有LIKE模糊匹配的分组查询》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何优化SQL中带有LIKE模糊匹配的分组查询》有用,将其分享出去将是对创作者最好的鼓励。

带有LIKE模糊匹配的分组查询在业务开发中十分常见,比如统计不同前缀的商品名称数量、筛选特定格式的日志信息并分组统计等场景,这类查询如果不做优化,很容易出现执行耗时过长的问题。传统方案下,数据库需要对全表数据进行扫描,逐行匹配LIKE条件后再做分组计算,当表数据量达到百万级以上时,查询耗时可能超过数秒,严重影响业务响应速度。

如何优化SQL中带有LIKE模糊匹配的分组查询

常规LIKE分组查询的性能问题

我们先来看一个典型的未优化的查询场景,假设有一张product表,存储了商品的基础信息,其中product_name是商品名称字段,现在需要统计所有以"手机"开头的商品名称对应的商品数量,常规SQL写法如下:

-- 未优化的LIKE前缀匹配分组查询
SELECT product_name, COUNT(*) AS product_count
FROM product
WHERE product_name LIKE '手机%'
GROUP BY product_name;

如果product_name字段没有合适的索引,这条语句会触发全表扫描,对每一行的product_name做字符串匹配,匹配成功后再参与分组计算。即使product_name有普通索引,LIKE以通配符开头的查询(比如'%手机%')也无法使用索引,只有前缀匹配的场景('手机%')才有可能使用到普通索引,但分组操作依然可能带来额外的排序开销。

利用前缀索引优化前缀匹配分组查询

如果LIKE查询都是前缀匹配的场景,也就是通配符只在末尾,比如'手机%''电脑%'这类,那么可以创建前缀索引来优化查询性能。前缀索引只对字段的前N个字符建立索引,相比全字段索引占用更小的存储空间,同时能提升匹配效率。

前缀索引的创建方式

创建前缀索引时需要选择合适的前缀长度,既要保证索引的选择性足够高,又要控制索引的大小。可以通过下面的SQL计算不同前缀长度的选择性:

-- 计算product_name不同前缀长度的选择性
SELECT 
  COUNT(DISTINCT LEFT(product_name, 3)) / COUNT(*) AS sel3,
  COUNT(DISTINCT LEFT(product_name, 5)) / COUNT(*) AS sel5,
  COUNT(DISTINCT LEFT(product_name, 7)) / COUNT(*) AS sel7,
  COUNT(DISTINCT LEFT(product_name, 10)) / COUNT(*) AS sel10
FROM product;

当某个前缀长度的选择性接近全字段的选择性时,就可以选择这个长度作为前缀索引的长度。假设计算后发现前缀长度为7时选择性已经足够高,那么可以创建前缀索引:

-- 创建product_name的前缀索引,前缀长度为7
CREATE INDEX idx_product_name_prefix ON product(product_name(7));

优化后的查询效果

创建前缀索引后,再执行之前的LIKE前缀匹配分组查询,数据库会优先使用前缀索引快速定位符合'手机%'条件的记录,减少全表扫描的开销,分组操作也可以利用索引的有序性减少排序成本,查询耗时通常会下降一个数量级。

需要注意的是,前缀索引只适用于LIKE前缀匹配的场景,如果LIKE查询是包含匹配('%手机%')或者后缀匹配('%手机'),前缀索引是无法生效的,这时候就需要考虑全文索引方案。

利用全文索引优化包含匹配分组查询

当LIKE查询是包含匹配或者后缀匹配,无法通过前缀索引优化时,全文索引是更合适的方案。全文索引会对文本字段的内容进行分词处理,建立倒排索引,能够快速定位包含指定关键词的记录,相比LIKE的逐行字符串匹配效率要高很多。

全文索引的创建与使用

首先需要在product_name字段上创建全文索引,不同数据库的全文索引语法略有差异,以MySQL为例:

-- 创建product_name字段的全文索引
CREATE FULLTEXT INDEX idx_product_name_fulltext ON product(product_name);

创建完成后,就可以使用全文索引的匹配语法来替换原来的LIKE查询,统计包含"手机"关键词的商品名称数量:

-- 使用全文索引的包含匹配分组查询
SELECT product_name, COUNT(*) AS product_count
FROM product
WHERE MATCH(product_name) AGAINST('手机' IN BOOLEAN MODE)
GROUP BY product_name;

全文索引的注意事项

  • 全文索引对短文本的分词效果可能有限,比如单个字符或者过短的关键词可能无法正确匹配,需要根据实际业务调整分词规则。
  • 全文索引的更新会有一定开销,如果表是写多读少的场景,需要评估索引维护对写入性能的影响。
  • 不同数据库对全文索引的支持程度不同,比如MySQL的全文索引对中文的支持需要开启ngram分词器,创建索引时需要指定分词长度,例如CREATE FULLTEXT INDEX idx_product_name_fulltext ON product(product_name) WITH PARSER ngram;

两种优化方案的对比与选择

我们可以通过下面的表格对比两种优化方案的适用场景和特点:

优化方案适用LIKE场景索引大小维护成本性能提升幅度
前缀索引仅前缀匹配('关键词%')较小
全文索引前缀、包含、后缀匹配均支持较大极高(尤其是包含匹配场景)

在实际业务中选择方案时,首先判断LIKE查询的模式,如果是固定的前缀匹配场景,优先选择前缀索引,成本和收益比更优;如果包含多种匹配模式,或者主要是包含、后缀匹配,那么选择全文索引更合适。同时要注意定期分析查询的执行计划,通过EXPLAIN命令查看索引是否被正确使用,及时调整索引策略。

优化后的效果验证

可以通过EXPLAIN命令对比优化前后的查询执行计划,优化前可能出现type: ALL的全表扫描标识,优化后应该出现type: range或者type: fulltext的索引使用标识,同时rows字段的扫描行数会大幅下降。比如优化前扫描100万行,优化后可能只需要扫描几千行,查询耗时从3秒下降到100毫秒以内,性能提升非常明显。

SQL优化LIKE模糊匹配全文索引前缀索引分组查询修改时间:2026-06-09 20:12:24

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。