You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化含大量LIKE条件的MySQL查询性能问题

25K行entities表关键词筛选优化方案

先修正否定条件的逻辑错误

你当前的否定条件逻辑完全错误——用OR会导致只要某一行不匹配其中一个否定关键词就被保留,根本达不到「排除所有包含任意否定关键词的行」的目的。正确逻辑应该是所有否定关键词都不匹配,要把否定条件里的OR换成AND:

SELECT id, title, description
FROM entities
WHERE 
(
    title LIKE '%keyword_1%' OR description LIKE '%keyword_1%' 
    OR title LIKE '%keyword_2%' OR description LIKE '%keyword_2%' 
    OR title LIKE '%keyword_3%' OR description LIKE '%keyword_3%' 
)
AND
(
    title NOT LIKE '%negative_keyword_1%' AND description NOT LIKE '%negative_keyword_1%' 
    AND title NOT LIKE '%negative_keyword_2%' AND description NOT LIKE '%negative_keyword_2%' 
    AND title NOT LIKE '%negative_keyword_3%' AND description NOT LIKE '%negative_keyword_3%' 
)

逻辑修正后,既能避免无效数据被保留,也能减少后续不必要的计算开销。

用布尔模式的全文索引替代LIKE

你之前用MATCH() AGAINST()性能差,大概率是没用到布尔模式,或者没创建正确的联合全文索引。

第一步:创建联合全文索引

针对title和description字段创建联合全文索引:

CREATE FULLTEXT INDEX idx_entities_title_desc ON entities(title, description);

第二步:用布尔模式编写查询

布尔模式支持+(必须包含)、-(必须排除)、*(通配符)等操作,完美适配你的需求:

SELECT id, title, description
FROM entities
WHERE MATCH(title, description) AGAINST(
    'keyword_1 keyword_2 keyword_3 -negative_keyword_1 -negative_keyword_2 -negative_keyword_3'
    IN BOOLEAN MODE
);

注:如果需求是「包含任意关键词」而非「包含所有关键词」,直接写关键词即可——布尔模式下默认是OR逻辑,只要匹配任意一个关键词就算符合条件;如果需要强制匹配所有关键词,给每个关键词加+前缀即可。

这个方案性能远优于LIKE,因为全文索引是专门为文本检索设计的,不会像LIKE那样触发全表扫描。

用正则表达式简化多LIKE的OR逻辑

如果暂时不想改全文索引,可以把多个LIKE的OR合并成一个REGEXP,减少SQL语句复杂度,也能小幅提升性能:

SELECT id, title, description
FROM entities
WHERE 
    (title REGEXP 'keyword_1|keyword_2|keyword_3' OR description REGEXP 'keyword_1|keyword_2|keyword_3')
    AND
    (title NOT REGEXP 'negative_keyword_1|negative_keyword_2|negative_keyword_3' AND description NOT REGEXP 'negative_keyword_1|negative_keyword_2|negative_keyword_3')

不过正则的性能仍不如全文索引,适合关键词数量不多的场景。

预处理分词存储(长期优化方案)

如果你的业务高频做这类关键词检索,可以提前把title和description的分词结果(比如用分词工具拆分后的词语)存储到单独字段,比如keywords:

  • 存储为逗号分隔字符串:'苹果,手机,智能',查询用FIND_IN_SET('keyword', keywords)
  • 或存储为JSON数组:["苹果","手机","智能"],查询用JSON_CONTAINS(keywords, '"keyword"')

这种方案需要在数据插入/更新时做预处理,但查询时性能极高,还能给预处理后的字段加普通索引进一步提速。

内容的提问来源于stack exchange,提问作者Vasyl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 15:35:21