
MySQL5.7版本,判断一行数据的多个数据列是否包含同一个值,示例是包含两个“重”的目标汉字 𨤶
①如果用函数REPLACE替换值为空字串计算长度差值,本身没有问题,但是用了函数包裹无法走索引,无论覆盖索引/复合索引还是单字段索引。
SELECT copyable_char, char_zone FROM `tb_comps` WHERE (LENGTH(CONCAT(`comp_top`,`comp6`,`comp5`,`comp4`,`comp3`,`comp2`,`comp1`,`supp1`,`supp2`,`supp3`,`supp4`,`supp5`,`supp6`,`supp_top`)) - LENGTH(REPLACE(CONCAT(`comp_top`,`comp6`,`comp5`,`comp4`,`comp3`,`comp2`,`comp1`,`supp1`,`supp2`,`supp3`,`supp4`,`supp5`,`supp6`,`supp_top`),'重','')) >= 2*LENGTH('重'))
②老版本的MySQL可以在数据列中存储CONCAT组合字段的计算列,为计算列添加索引。
③新版本MySQL8.0+,可以直接添加函数索引,即是为上述CONCAT(`comp_top`,`comp8`,`comp7`,`comp6`,`comp5`,`comp4`,`comp3`,`comp2`,`comp1`,`supp1`,`supp2`,`supp3`,`supp4`,`supp5`,`supp6`,`supp7`,`supp8`,`supp_top`)涉及到的列函数添加复合索引。
既要 基于目前使用的版本MySQL5.7版本,无法添加函数索引,但是肯定想要走索引不想全表扫描,那么只有走②方案增加字段添加计算列为计算列添加索引吗?不太想这样做增加存储
又要 有无方案 不用函数的情况下(这样就可以容易地创建多条复合索引实现“索引覆盖”,字段比较多,一条覆盖索引MySQL限制16个字段)替代①方案 实现判断一行数据的多个数据列是否包含同一个值?
还要 SQL语句尽量简单,便于动态拼接SQL,因为还要遍历前端字符串处理后的HashMap传参动态拼接SQL。
上面的 ,'重','')) >= 2*LENGTH('重')) 部分是 遍历处理好的 前端查询字符串拆分为单个字符的出现次数 的Map或HashMap {重:2} 动态拼接SQL传参。
可能还要 这种判断多列值的情况下,可能后续列值还会超过50~100列,用关系型数据库好还是ElasticSearch缓存一下比较好?
我的理解是,索引是为了查询。处理的事情可以交给代码。