实践出真知,欢迎关注我的公众号:Hoeller
今天给大家分享一个小知识,实际项目中,like %xxx%
的情况其实挺多的,比如某个表单如果支持根据公司名进行搜索,用户一般都是输入湖南xxx有限公司中的xxx进行搜索,所以对于接口而言,就必须使用like %xxx%
来支持,从而不符合最左前缀原则导致索引失效,那么该如何优化这种情况呢?
第一种可以尝试的方案就是利用索引条件下推,我先演示再讲原理,比如我有下面一张订单表:
就算给company_name
创建一个索引,执行where company_name like '%腾讯%'
也不会走索引。
但是如果给created_at, company_name
创建一个联合索引,那么执行where created_at=CURDATE() and company_name like '%腾讯%'
就会走联合索引,并且company_name like '%腾讯%'
就会利用到索引条件下推机制,比如下图中Extra里的Using index condition
就表示利用了索引条件下推。
所以,并不是like %xxx%
就一定会导致索引失效,原理也可以配合其他字段一起来建联合索引,从而使用到索引条件下推机制。
再来简单分析一下索引条件下推的原理,在执行查询时先利用SQL中所提供的created_at条件在联合索引B+树中进行快速查找,匹配到所有符合created_at条件的B+树叶子节点后,再根据company_name条件进行过滤,然后再根据过滤之后的结果中的主键ID进行回表找到其他字段(回表),最终才返回结果,这样处理的好处是能够减少回表的次数,从而提高查询效率。
当然,如果实在不能建立或不方便建立联合索引,导致不能利用索引条件下推机制,那么其实可以先试试Mysql中的全文索引,最后才考虑引入ES等中间件,当然Mysql其他一些常规优化机制也是可以先考虑的,比如分页、索引覆盖(不select *)等。
我是大都督,之前是一名讲师,现在是一名架构师,实践才能出真知,这是我重回一线的原因!如果大家觉得有所收获,不想错过更多实战干货高质量技术文章,可以关注我的公众号:Hoeller。