查询符号匹配数组或名称以数组元素开头的行及索引优化方案
完整查询语句实现
两个匹配条件为或逻辑,其中name字段要求以目标词开头,属于前缀匹配场景,必须使用关键词%的模糊匹配规则,不能加前导%,否则无法命中索引。
针对示例的匹配数组["xjf","bly","xxx","colins"],完整SQL如下:
SELECT symbol, name FROM index_v1 WHERE symbol IN ('xjf', 'bly', 'xxx', 'colins') OR name LIKE 'xjf%' OR name LIKE 'bly%' OR name LIKE 'xxx%' OR name LIKE 'colins%';
如果是动态传入匹配数组,直接在应用层遍历数组元素,拼接对应的symbol IN值列表和OR name LIKE '元素值%'片段即可,不要在字段上套函数做匹配,避免索引失效。
如果使用的数据库对OR条件的索引合并支持不好,可以拆成UNION写法,返回结果和原逻辑完全一致,执行效率更稳定:
-- 匹配symbol等值的结果集 SELECT symbol, name FROM index_v1 WHERE symbol IN ('xjf', 'bly', 'xxx', 'colins') UNION -- 匹配name前缀的结果集,UNION自动对两个结果集的重复行去重 SELECT symbol, name FROM index_v1 WHERE name LIKE 'xjf%' OR name LIKE 'bly%' OR name LIKE 'xxx%' OR name LIKE 'colins%';
索引优化方案
当前表仅5000行数据,全表扫描的性能损耗也极低,如果要适配后续数据量增长,按以下规则建索引即可:
- 针对
symbol字段的等值匹配需求:因为symbol字段值全局唯一,直接建唯一B树索引,等值查询时间复杂度为O(logn),效率最高CREATE UNIQUE INDEX idx_symbol ON index_v1(symbol); - 针对
name字段的前缀匹配需求:直接给name字段建普通B树索引即可,LIKE '关键词%'的前缀匹配符合B树最左匹配原则,可以直接命中索引,不需要建全文索引CREATE INDEX idx_name ON index_v1(name);
注意避坑:不要使用
LEFT(name, 字符长度) = 关键词这类函数写法实现前缀匹配,函数包裹字段会导致数据库无法使用字段上的索引,触发全表扫描。
内容的提问来源于stack exchange,提问作者gotiredofcoding
相关产品推荐
相关产品推荐

