当查询条件不断变化时,Mysql应如何按照最左匹配原则建立复合索引?
假如有个歌手表(singers),数据量在300w行,以下是部分字段。
(好吧不是假如,而是接手了一个项目,改表的话难度有点大)
id | 姓名 | 是否开启 | 是否记录 | 热度 | 点击量 | 排序 | 创建时间 |
---|---|---|---|---|---|---|---|
id(bigint) | name(varchar) | is_open(tinyint) | is_rec(tinyint) | hot(bigint) | hits(bigint) | sort(bigint) | created_at(int) |
is_open、is_rec只有0,1
业务现在可能出现以下查询(场景一)
where name='xxx' and is_open=0 and is_rec=0 order by hot desc,hits desc
where is_open=0 and is_rec=0 order by hot desc,hits desc
按照最左匹配原则,建立索引的话。
create index singers_index on singers (name,is_open,is_rec,hot,hits)
那么上面场景一的第二句就无法使用索引了。就算把name放到is_rec后面也是不行的。
业务现在可能出现以下查询(场景二)
where is_open=0 and is_rec=0 order by hot desc,hits desc
where is_open=0 and is_rec=0 order by hot desc,sort desc
按照最左匹配原则,建立索引的话。
create index singers_index on singers (is_open,is_rec,hot,hits,sort)
场景二第二句也无法使用索引。因为hits没有命中。不能再建一条以sort结尾的复合索引吧。假如又有其他字段参与排序,那肯定不行的。而且两个场景的索引又出现了重复。
以上是简单描述了一下遇到的场景,还有其他的场景在这个表上操作。
现在的问题就是业务上有各种查询和排序的组合,而能用到的索引只能满足一种最左匹配原则。建立多个复合索引是不现实的。网上也搜过很多资料,大部分只说明最左匹配原则,然后建立一条索引,但是这种原则限制了很多查询导致索引无法使用。
请教各位,现应该如何着手优化这些sql语句或者建立一个通用的复合索引。
首先汇总下所有的查询条件语句,然后根据大部分的查询语句,建立合适的最左前缀匹配索引,如果实在不行的话,跟业务方谈下,实际使用,而且查询二中的,应该会命中最左前缀匹配原则才对的,只是key_len不一样吧
is_open、is_rec 只有 0,1
,这样的字段重复值太多,并不适合建立索引,回表次数太多,还不如全表扫描。或许直接强制使用索引?force index(singers_index )
你好,我也遇到了同样的问题,请问您的问题解决了吗
@devilcry52 你好