表结构及数据量
CREATE TABLE `tb_habit_log_total` (
`totalID` INT(11) NOT NULL AUTO_INCREMENT,
`openId` VARCHAR(100) COLLATE UTF8MB4_UNICODE_CI NOT NULL DEFAULT '',
`habitID` INT(11) NOT NULL,
`joinCreateDate` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`totalSuccessDay` INT(11) DEFAULT '0',
`totalLastDate` DATE DEFAULT NULL,
`joinState` TINYINT(1) DEFAULT '1',
`totalAdminRole` TINYINT(1) DEFAULT '0',
PRIMARY KEY (`totalID`),
UNIQUE KEY `uk_hid_oid` (`habitID` , `openId`) USING BTREE,
KEY `openId` (`openId`),
KEY `idx_totalSuccessDay` (`totalSuccessDay`),
KEY `idx_totalLastDate` (`totalLastDate`),
KEY `idx_totalAdminRole` (`totalAdminRole`),
KEY `idx_joinCreateDate` (`joinCreateDate`),
KEY `idx_hid_js_tid` (`habitID` , `joinState` , `totalID` , `joinCreateDate`) USING BTREE
) ENGINE=INNODB AUTO_INCREMENT=22854700 DEFAULT CHARSET=UTF8MB4;
索引情况
然后看看诡异的执行计划,这俩只是habitID不同
看看各自的数据量
尽管数据量不一样,但这也不应该是MySQL选择走totalID索引的理由,因为where条件加order by条件以及limit条件可以确定走idx_hid_js_tid索引才是最快的,排序可以直接通过索引排,取前10条返回就OK
最后发现,order by把联合索引都指定上的话,MySQL终于选对索引了