这篇文章主要讲的是使用in查询,联合索引是否会生效的问题         
 首先简单说一下联合索引:联合索引又叫复合索引,是由表中的几个列联合组成的索引。联合索引生效需满足最左前缀原则,即如果联合索引列为a,b,c三列,a,b,c 、a,b 、a生效,b,c、a,c、b、c等不生效(此处的顺序不是where条件后面的先后顺序,而是where条件中是否存在这些列,如果where中只存在a,c列,则不生效)。
CREATE TABLE `aaa` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `app_id` int(8) DEFAULT NULL,
  `child_id` int(8) DEFAULT NULL,
  `channel_id` int(8) DEFAULT NULL,
  `app_channel_id` int(8) DEFAULT NULL,
  `startup_count` int(10) DEFAULT '0' COMMENT '启动次数',
  `date` date DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `appchannleid_date` (`app_id`,`child_id`,`channel_id`,`app_channel_id`,`date`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=355 DEFAULT CHARSET=utf8;
此时索引生效:
SELECT * FROM aaa a 
WHERE 1=1 and a.app_id='10026' and a.child_id='13'(或WHERE 1=1 and a.child_id='13' and a.app_id='10026')

此时索引失效:

SELECT * FROM aaa a 
WHERE 1=1 and a.child_id='13' and a.channel_id='3'

下面说一下使用in时联合索引的问题

还是使用上面那张表,in里面的数据是一个时,索引有效,大于一个时,索引失效,具体原因还没找到,有时间在研究。所以使用了强制索引使索引生效。

索引生效:

SELECT * FROM stat_app_channel_id_device_active_2018 a 
WHERE 1=1 and a.app_id in ( '10026'  ) order by date desc,id ASC limit 30 

索引失效:

SELECT * FROM stat_app_channel_id_device_active_2018 a 
WHERE 1=1 and a.app_id in ( '10026' , '10000' ) order by date desc,id ASC limit 30 

索引生效:

SELECT * FROM stat_app_channel_id_device_active_2018 a force index(appchannleid_date) 
WHERE 1=1 and a.app_id in ( '10026' , '10000' ) order by date desc,id ASC limit 30 

什么时候索引生效:
1.表中含有索引。
2.查询时全表扫描比使用索引效率低时(大多数情况效率低,当数据量少或其他特殊情况下,全表扫描比使用索引效率高时,mysql不使用索引)。
3.满足索引生效的规则(例如表中是数值类型,传参是字符串类型)。

什么时候使用强制索引 force index:当我们确定要使用一个索引进行查询时,就可以使用强制索引。但使用强制索引后,mysql优化器不会在指定到其他的索引上,不管查询条件如何变,都会使用该索引进行查询。

Logo

更多推荐