当查询条件不断变化时,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语句或者建立一个通用的复合索引。

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 5
╰ゝSakura

首先汇总下所有的查询条件语句,然后根据大部分的查询语句,建立合适的最左前缀匹配索引,如果实在不行的话,跟业务方谈下,实际使用,而且查询二中的,应该会命中最左前缀匹配原则才对的,只是key_len不一样吧

3年前 评论
devilcry52 (楼主) 3年前

is_open、is_rec 只有 0,1,这样的字段重复值太多,并不适合建立索引,回表次数太多,还不如全表扫描。

3年前 评论
devilcry52 (楼主) 3年前

或许直接强制使用索引?force index(singers_index )

3年前 评论
devilcry52 (楼主) 3年前
devilcry52 (楼主) 3年前

你好,我也遇到了同样的问题,请问您的问题解决了吗

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!