标签:varchar 主键 oss 实战 lte 简单的 art var 部分
需要查询的值已经在索引里面包含了,就不需要查询数据行了。
mysql> explain select * from person1 where a like ‘%12%‘;
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| 1 | SIMPLE | person1 | NULL | ALL | NULL | NULL | NULL | NULL | 98999 | 11.11 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select a from person1 where a like ‘%12%‘;
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+--------------------------+
| 1 | SIMPLE | person1 | NULL | index | NULL | index_A_B_C | 21 | NULL | 98999 | 11.11 | Using where; Using index |
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+--------------------------+
1 row in set, 1 warning (0.01 sec)
这个可能不是一个恰当的例子,但是事实上覆盖索引往往都要比非覆盖索引要高。
不是所有的值都能覆盖索引,比方说hash,空间索引,文本索引就不行,只有B-Tree索引才带数据
mysql> explain select store_id,film_id from inventory;
+----+-------------+-----------+------------+-------+---------------+----------------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+----------------------+---------+------+------+----------+-------------+
| 1 | SIMPLE | inventory | NULL | index | NULL | idx_store_id_film_id | 3 | NULL | 4581 | 100.00 | Using index |
+----+-------------+-----------+------------+-------+---------------+----------------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from inventory;
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | inventory | NULL | ALL | NULL | NULL | NULL | NULL | 4581 | 100.00 | NULL |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
可以发现只查索引字段时候 extra 中显示的是using index 但是select All的时候却没有使用索引了
mysql> explain select * from person_index where a = 12;
+----+-------------+--------------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| 1 | SIMPLE | person_index | NULL | ALL | index_a_b_c | NULL | NULL | NULL | 98999 | 10.00 | Using where |
+----+-------------+--------------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 3 warnings (0.00 sec)
mysql> explain select a from person_index where a = 12;
+----+-------------+--------------+------------+-------+---------------+-------------+---------+------+-------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------+------------+-------+---------------+-------------+---------+------+-------+----------+--------------------------+
| 1 | SIMPLE | person_index | NULL | index | index_a_b_c | index_a_b_c | 21 | NULL | 98999 | 10.00 | Using where; Using index |
+----+-------------+--------------+------------+-------+---------------+-------------+---------+------+-------+----------+--------------------------+
1 row in set, 3 warnings (0.00 sec)
where条件里面有相关的字段,但是最终的查询结果字段集合里面还有其他的字段,那么也不会使用索引
ysql> explain select * from person_index inner join (select version from person where a =12) as t1 on t1.version = person_index.version;
+----+-------------+--------------+------------+--------+---------------+---------+---------+--------------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------+------------+--------+---------------+---------+---------+--------------------+------+----------+-------------+
| 1 | SIMPLE | person | NULL | ref | PRIMARY,A | A | 4 | const | 1100 | 100.00 | Using index |
| 1 | SIMPLE | person_index | NULL | eq_ref | PRIMARY | PRIMARY | 22 | dev.person.version | 1 | 100.00 | NULL |
+----+-------------+--------------+------------+--------+---------------+---------+---------+--------------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
先查处一部分数据再使用关联来做好歹也用一部分索引
mysql> explain select * from tb_user where user_name like ‘admin11%‘;
+----+-------------+---------+------------+-------+---------------+---------+---------+------+-------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+-------+----------+-------------+
| 1 | SIMPLE | tb_user | NULL | range | PRIMARY | PRIMARY | 202 | NULL | 22436 | 100.00 | Using where |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from tb_user where user_name like ‘%admin11%‘;
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | tb_user | NULL | ALL | NULL | NULL | NULL | NULL | 992136 | 11.11 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select user_name from tb_user where user_name like ‘%admin11%‘;
+----+-------------+---------+------------+-------+---------------+---------+---------+------+--------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+--------+----------+--------------------------+
| 1 | SIMPLE | tb_user | NULL | index | NULL | PRIMARY | 202 | NULL | 992136 | 11.11 | Using where; Using index |
+----+-------------+---------+-----------
这里和书上的不一样,覆盖索引现在支持了以通配符开头的查询
但是也不能迷信使用延迟关联的方式去查询,因为关联是有性能损耗的,在本身数据量就很小的情况下没有必要这样处理,反而会影响性能。
因为在二级索引里面会带上主键的值所以在查询的时候可以利用这一点来做覆盖索引:
mysql> explain select * from person where a = 12;
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | person | NULL | ref | A | A | 4 | const | 1100 | 100.00 | Using index |
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> show create table person ;
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| person | CREATE TABLE `person` (
`A` int(50) NOT NULL,
`B` int(50) NOT NULL,
`C` int(50) NOT NULL,
`version` varchar(20) NOT NULL,
PRIMARY KEY (`version`),
KEY `A` (`A`,`B`,`C`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
person
里面总共就4个字段a,b,c是联合索引,version是主键,所以在使用a的联合索引的时候实际上就有这个4个字段,所以有 using index;
标签:varchar 主键 oss 实战 lte 简单的 art var 部分
原文地址:https://www.cnblogs.com/lijunyzzZ/p/14747723.html