mysql聚合索引失效
索引是可以高效的获取数据的数据结构, 对查询有很大作用. 索引对于数据库, 就像偏旁部首, 或者26个英文字母对于字典一样, 能很快的提高查询速度.但是索引也有它的缺点:首先就是占用磁盘空间其次是虽然...
2024.11.15之前开发发起建表申请时,有时会创建复合索引,可是应用上线之后,数据库监控到很多慢sql,和开发一沟通,开发觉得写的sql应该走创建的复合索引呀,可是为什么不走呢?原来是开发人员没有理解Mysql复合索引最左匹配原则,在这里就详细解释一下什么是最左匹配原则。
mysql的最左原则,就是从左至右匹配,直到遇到(>, explain select * from t_test2 where name= ‘jest1‘ and depno =101 and dep_name=‘jf112l‘;+----+-------------+---------+------------+------+---------------------------------+---------------------------------+---------+-------------------+------+----------+-------+| id | select_type | table| partitions | type | possible_keys| key | key_len | ref| rows | filtered | Extra |+----+-------------+---------+------------+------+---------------------------------+---------------------------------+---------+-------------------+------+----------+-------+|1 | SIMPLE| t_test2 | NULL| ref| idx_t_test2_name_depno_dep_name | idx_t_test2_name_depno_dep_name | 36| const,const,const |1 |100.00 | NULL|+----+-------------+---------+------------+------+---------------------------------+---------------------------------+---------+-------------------+------+----------+-------+1 row in set, 1 warning (0.00 sec)
写到这里,不知道你心里有没有一个疑问,执行计划中的索引dx_t_test2_name_depno_dep_name到底用到了几个字段,怎么能判断呢
我们可以通过执行计划里的key_len的值,来了解mysql到底匹配哪几个字段,在这里讲解一下key_len的含义
key_len:显示MySQL实际使用的索引的长度。如果索引为NULL,则长度也为NULL。如果不是NULL,则为使用的索引的长度。所以可以通过此字段推断出使用了哪个索引字段。key_len的计算规则如下所示:1.定长字段,int占用4个字节,date占用3个字节,char(n)占用n个字符。2.变长字段varchar(n),占用n个字符加两个字节。3.需要注意的是,不同的字符集,一个字符占用的字节数是不同的。例如:Latin1编码的,一个字符占用一个字节,gdk编码的,一个字符占用两个字节,utf-8编码的,一个字符占用三个字节,而utf8mb4,一个字符则占用四个字节。4.对于所有的索引字段,如果设置为NULL,则额外需要占用一个字节。
知道了key_len的计算规则,那来看看上面的执行计划,key_len的值为36是怎么计算出来。首先字符集为latin1,name为char(10),则key_len为10,dep_no为int(10),则key_len为4,dep_name为varchar(20),则key_len为22,三个字段的key_len总和为36,是不是就对应上了。
知道原理之后,下面看测试用例就非常简单了
mysql> explain select * from t_test2 where name= ‘jest1‘ and depno >101 and dep_name=‘jf112l‘;+----+-------------+---------+------------+-------+---------------------------------+---------------------------------+---------+------+------+----------+-----------------------+| id | select_type | table| partitions | type| possible_keys| key | key_len | ref| rows | filtered | Extra |+----+-------------+---------+------------+-------+---------------------------------+---------------------------------+---------+------+------+----------+-----------------------+|1 | SIMPLE| t_test2 | NULL| range | idx_t_test2_name_depno_dep_name | idx_t_test2_name_depno_dep_name | 14| NULL |2 |10.00 | Using index condition |+----+-------------+---------+------------+-------+---------------------------------+---------------------------------+---------+------+------+----------+-----------------------+1 row in set, 1 warning (0.00 sec)key_len值为14,索引使用的字段为name和depno,因为遇到>,就停止了。有同学会说,那>=呢,实践出真理,测试一下就知道结果
mysql> explain select * from t_test2 where name= ‘jest1‘ and depno >=101 and dep_name=‘jf112l‘;+----+-------------+---------+------------+-------+---------------------------------+---------------------------------+---------+------+------+----------+-----------------------+| id | select_type | table| partitions | type| possible_keys| key | key_len | ref| rows | filtered | Extra |+----+-------------+---------+------------+-------+---------------------------------+---------------------------------+---------+------+------+----------+-----------------------+|1 | SIMPLE| t_test2 | NULL| range | idx_t_test2_name_depno_dep_name | idx_t_test2_name_depno_dep_name | 36| NULL |2 |10.00 | Using index condition |+----+-------------+---------+------------+-------+---------------------------------+---------------------------------+---------+------+------+----------+-----------------------+1 row in set, 1 warning (0.01 sec)看到没有key_len的值为36,就是说>=,复合索引是可以匹配的。
当查询条件中包含like时,得看like后面首个字符是否是通配符,如果是,则终止,如果不是,则复合索引是可以匹配的。
mysql> explain select * from t_test2 where name= ‘jest1‘ and depno =101 and dep_name like ‘jf112l%‘;+----+-------------+---------+------------+-------+---------------------------------+---------------------------------+---------+------+------+----------+-----------------------+| id | select_type | table| partitions | type| possible_keys| key | key_len | ref| rows | filtered | Extra |+----+-------------+---------+------------+-------+---------------------------------+---------------------------------+---------+------+------+----------+-----------------------+|1 | SIMPLE| t_test2 | NULL| range | idx_t_test2_name_depno_dep_name | idx_t_test2_name_depno_dep_name | 36| NULL |1 |100.00 | Using index condition |+----+-------------+---------+------------+-------+---------------------------------+---------------------------------+---------+------+------+----------+-----------------------+1 row in set, 1 warning (0.00 sec)mysql> mysql> explain select * from t_test2 where name= ‘jest1‘ and depno =101 and dep_name like ‘%jf112l%‘;+----+-------------+---------+------------+------+---------------------------------+---------------------------------+---------+-------------+------+----------+-----------------------+| id | select_type | table| partitions | type | possible_keys| key | key_len | ref | rows | filtered | Extra |+----+-------------+---------+------------+------+---------------------------------+---------------------------------+---------+-------------+------+----------+-----------------------+|1 | SIMPLE| t_test2 | NULL| ref| idx_t_test2_name_depno_dep_name | idx_t_test2_name_depno_dep_name | 14| const,const |1 |11.11 | Using index condition |+----+-------------+---------+------------+------+---------------------------------+---------------------------------+---------+-------------+------+----------+-----------------------+1 row in set, 1 warning (0.00 sec)好了,今天就写到这里,如果觉得对你有帮助,请加关注,点赞,分享或者留言。
索引是可以高效的获取数据的数据结构, 对查询有很大作用. 索引对于数据库, 就像偏旁部首, 或者26个英文字母对于字典一样, 能很快的提高查询速度.但是索引也有它的缺点:首先就是占用磁盘空间其次是虽然...
2024.11.15MySQL索引有哪些类型MySQL目前主要有以下几种索引类型:普通索引:最基本的索引,没有任何限制条件。唯一索引:与普通索引类似,但要求索引列的值唯一,不允许重复。主键索引:是一种特殊的唯一索引,不允...
2024.11.12在设计MySQL索引时,需要考虑以下八大原则:最左前缀原则:复合索引按照从左到右的顺序进行匹配,如果查询条件中包含了复合索引的最左侧的列,则该索引会被使用。选择性原则:索引的选择性越高,即不同值之间的...
2024.11.12一步一步推导出 Mysql 索引的底层数据结构。Mysql 作为互联网中非常热门的数据库,其底层的存储引擎和数据检索引擎的设计非常重要,尤其是 Mysql 数据的存储形式以及索引的设计,决定了 Mys...
2024.11.10概述之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章,讲的都比较泛,所以今天在这里自己整理一下这方面的内容,做个备忘!Mysql中联合索引的最左匹配原则在Mysql建立多列索引(联合索引)...
2024.11.15