索引是什么

是存储引擎用于找到数据的一种数据结构。

C/C++ Linux服务器开发高级架构视频点击:C/C++Linux服务器开发高级架构师/Linux后台架构师-学习视频

MYSQL索引优化视频详解:深入理解MySQL—索引及其优化

索引的性能

在数据量小的时候,一个坏的索引往往作用没有那么明显,但是在数据量比较大的时候一个坏的索引和好的索引有巨大的区别。

在查询优化的时候应该首先考虑索引优化。这个是最简单的,也是效果最好。

索引的执行流程

索引 => 索引值 => 数据行

mysql> explain select first_name from actor where actor_id = 5;
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | actor | NULL       | const | PRIMARY       | PRIMARY | 2       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

通过explian可以看到where条件后面是使用了主键索引。

多列索引

如果是多列组成的索引,那么在使用索引的时候要考虑索引的顺序。
多列索引有如下原则

  • 最左匹配原则,如果缺失了索引的最左侧列,那么索引不生效
  • 中间不可中断原则,如果中间定义的索引没有在where条件里面体现,那么后面的字段过滤将不会用到索引
  • 范围中断原则,只要使用了范围查询,那么其右侧的索引都无法正常使用

多列索引的验证

建表语句

create table person
(A INT(10) not null,B INT(10) not null,C INT(10) not null,version VARCHAR(20) not null
);create index Aon person (A, B, C);

填充数据的存储过程

delimiter //
//
CREATE DEFINER=`dev`@`%` PROCEDURE `insert_person`(IN item int)
BEGIN
DECLARE counter INT;
SET counter = item;
WHILE counter >= 1000 DO
INSERT INTO person VALUES(left(counter, 2),left(counter,3), counter,counter );
SET counter = counter - 1;
END WHILE;
END;
//
delimiter ;
call insert_person(100000);

数据详情

mysql> select count(*) from person;
+----------+
| count(*) |
+----------+
|   100000 |
+----------+
1 row in set (0.04 sec)

场景分析

一、索引生效

1. 符合多列索引生效的三个原则,全部用上了索引

(a) 只对A做等值查询

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 | NULL  |
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

可以看到是用到了A的索引的。

(b)只对A做范围查询,并且结果集覆盖索引的时候。

mysql> explain select A,B,C from person  where A > 13;
+----+-------------+--------+------------+-------+---------------+------+---------+------+-------+----------+--------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  | rows  | filtered | Extra                    |
+----+-------------+--------+------------+-------+---------------+------+---------+------+-------+----------+--------------------------+
|  1 | SIMPLE      | person | NULL       | range | A             | A    | 4       | NULL | 49555 |   100.00 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+------+---------+------+-------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)

(c)对A,B做等值查询

mysql> explain select A,B,C from person  where A = 13 and b = 129;
+----+-------------+--------+------------+------+---------------+------+---------+-------------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref         | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+-------------+------+----------+-------------+
|  1 | SIMPLE      | person | NULL       | ref  | A             | A    | 8       | const,const |    1 |   100.00 | Using index |
+----+-------------+--------+------------+------+---------------+------+---------+-------------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

(d) 对A做等值,B做范围

mysql> explain select A,B,C from person  where A = 13 and b > 129;
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | person | NULL       | range | A             | A    | 8       | NULL | 1100 |   100.00 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+

(e) ABC等值查询

mysql> explain select A,B,C from person  where A = 12 and b = 129 and c = 1294;
+----+-------------+--------+------------+------+---------------+------+---------+-------------------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref               | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+-------------------+------+----------+-------------+
|  1 | SIMPLE      | person | NULL       | ref  | A             | A    | 12      | const,const,const |    1 |   100.00 | Using index |
+----+-------------+--------+------------+------+---------------+------+---------+-------------------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

(f) 对AB做等值,C范围查询

mysql> explain select A,B,C from person  where A = 12 and b = 129 and c > 1294;
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | person | NULL       | range | A             | A    | 12      | NULL |  105 |   100.00 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)

关于C/C++ Linux后端开发网络底层原理知识 点 后端开发学习资料 获取,内容知识点包括Linux,Nginx,ZeroMQ,MySQL,Redis,线程池,MongoDB,ZK,Linux内核,CDN,P2P,epoll,Docker,TCP/IP,协程,DPDK等等。

二、索引部分生效

满足最左原则,但是不满足中间不中断或者范围中断。
(a) 对A做等值,C做等值或者是范围

mysql> explain select * from person where  A = 12 and c = 1230;
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-----------------------+
| 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 |    10.00 | Using index condition |
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)mysql> explain select * from person where  A = 12 and c >1230;
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-----------------------+
| 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 |    33.33 | Using index condition |
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

(b)对A做等值,B做范围,C做等值或者范围,B做了范围查询之后,无法对C正常使用索引

mysql> explain select * from person where  A = 12 and b > 123 and c >1230;
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
| id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | person | NULL       | range | A             | A    | 8       | NULL |  660 |    33.33 | Using index condition |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)mysql> explain select * from person where  A = 12 and b = 123 and c >1230;
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
| id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | person | NULL       | range | A             | A    | 12      | NULL |  109 |   100.00 | Using index condition |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

(c) 对A做范围查询,BC做等值或者范围,那么BC将不会使用索引

mysql> explain select A,B,C  from person where  A > 12 and b > 123 and c >1230;
+----+-------------+--------+------------+-------+---------------+------+---------+------+-------+----------+--------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  | rows  | filtered | Extra                    |
+----+-------------+--------+------------+-------+---------------+------+---------+------+-------+----------+--------------------------+
|  1 | SIMPLE      | person | NULL       | range | A             | A    | 4       | NULL | 49555 |    11.11 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+------+---------+------+-------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)

需要注意的是这个地方ABC只是普通的索引如果是select * from,那么将不会使用索引。因为还有一个字段不再索引持有的数据上。

三、多列索引失效:

(a)查询条件中不包含最左列

mysql> explain select * from person where  b = 123 and c >1230;
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | person | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 99110 |     3.33 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)mysql> explain select * from person where  b = 123-> ;
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | person | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 99110 |    10.00 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)mysql> explain select * from person where  b >123;
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | person | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 99110 |    33.33 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from person where  c =123;
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | person | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 99110 |    10.00 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from person where  c >123;
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | person | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 99110 |    33.33 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.01 sec)

(b) 含有最左列,但是索引的列带条件

mysql> explain select * from person where  a + 1 =12;
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | person | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 99110 |   100.00 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)## 从哪里带条件哪里就不开始使用索引
mysql> explain select * from person where  a =12 and b + 1 = 123;
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-----------------------+
| 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 condition |
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

四、order by使用索引

(a) order by 字段的顺序和table中多列索引定义的顺序一样。


mysql> explain select * from person1 order by a,b, c;
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+----------------+
| 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 |   100.00 | Using filesort |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+----------------+
1 row in set, 1 warning (0.00 sec)mysql> explain select a,b,c from person1 order by a,b, c;
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-------------+
| 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 |   100.00 | Using index |
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

order by 不使用索引

(a) order by多个字段,每个字段都是独立的索引

mysql> create table person2 select * from person1;
Query OK, 99001 rows affected (0.68 sec)
Records: 99001  Duplicates: 0  Warnings: 0mysql> alter table add key(a);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'add key(a)' at line 1
mysql> alter table add index_a key(a);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'add index_a key(a)' at line 1
mysql> alter table add index  key(a);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'add index  key(a)' at line 1
mysql> alter table add index index_a key(a);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'add index index_a key(a)' at line 1
mysql> alter table add index index_a(a);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'add index index_a(a)' at line 1
mysql> alter table person2 add index index_a(a);
Query OK, 0 rows affected (0.15 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> alter table person2 add index index_b(b);
Query OK, 0 rows affected (0.15 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> explain select * from person2 order by a,b;
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+----------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra          |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+----------------+
|  1 | SIMPLE      | person2 | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 99110 |   100.00 | Using filesort |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+----------------+
1 row in set, 1 warning (0.00 sec)

(b) order by语句中同时含有desc和asc

mysql> explain select a,b,c from person1 order by a desc ;
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-------------+
| 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 |   100.00 | Using index |
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.01 sec)mysql> explain select a,b,c from person1 order by a desc ,b asc;
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-----------------------------+
| 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 |   100.00 | Using index; Using filesort |
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)

(c) order by 里面有计算字段

mysql> explain select a,b,c from person1 order by a desc ,b  + 1-> ;
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-----------------------------+
| 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 |   100.00 | Using index; Using filesort |
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)

(d) orderby 里面顺序和索引的顺序不同


mysql> explain select a,b,c from person1 order by b,a;
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-----------------------------+
| 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 |   100.00 | Using index; Using filesort |
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)

(e) group by 和orderby 的顺序不同

mysql> explain select a,b,c from person1 group by a,b,c order by a,b;
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys | key         | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | person1 | NULL       | index | index_A_B_C   | index_A_B_C | 21      | NULL | 98999 |   100.00 | Using index |
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select a,b,c from person1 group by a,b,c order by b,a;
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+----------------------------------------------+
| id | select_type | table   | partitions | type  | possible_keys | key         | key_len | ref  | rows  | filtered | Extra                                        |
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+----------------------------------------------+
|  1 | SIMPLE      | person1 | NULL       | index | index_A_B_C   | index_A_B_C | 21      | NULL | 98999 |   100.00 | Using index; Using temporary; Using filesort |
+----+-------------+---------+------------+-------+---------------+-------------+---------+------+-------+----------+----------------------------------------------+
1 row in set, 1 warning (0.00 sec)

上面的查询顺序一样,没有filesort,下面的不一样,就用了

(f) join查询的时候order只能按照主键的来排序,否则就会失效

mysql> explain select *  from person3 t1 left join person4 t2 on t1.version = t2.version where t1.version = 1200  order by t1.version;
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref            | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
|  1 | SIMPLE      | t1    | NULL       | index  | PRIMARY       | PRIMARY | 22      | NULL           |  101 |    10.00 | Using where |
|  1 | SIMPLE      | t2    | NULL       | eq_ref | PRIMARY       | PRIMARY | 22      | dev.t1.version |    1 |   100.00 | NULL        |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
2 rows in set, 3 warnings (0.00 sec)mysql> explain select *  from person3 t1 left join person4 t2 on t1.version = t2.version where t1.version = 1200  order by t2.version;
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+----------------------------------------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref            | rows | filtered | Extra                                        |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+----------------------------------------------+
|  1 | SIMPLE      | t1    | NULL       | ALL    | PRIMARY       | NULL    | NULL    | NULL           |  101 |    10.00 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | t2    | NULL       | eq_ref | PRIMARY       | PRIMARY | 22      | dev.t1.version |    1 |   100.00 | NULL                                         |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+----------------------------------------------+
2 rows in set, 3 warnings (0.00 sec)mysql> show create table person3;
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                                                                                |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| person3 | CREATE TABLE `person3` (`A` varchar(10) DEFAULT NULL,`B` int(50) NOT NULL,`C` int(50) NOT NULL,`version` varchar(20) NOT NULL,PRIMARY KEY (`version`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> show create table person4;
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                                                                                |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| person4 | CREATE TABLE `person4` (`A` varchar(10) DEFAULT NULL,`B` int(50) NOT NULL,`C` int(50) NOT NULL,`version` varchar(20) NOT NULL,PRIMARY KEY (`version`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> explain select *  from person3 t1 left join person4 t2 on t1.version = t2.version order by t1.version;
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref            | rows | filtered | Extra |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------+
|  1 | SIMPLE      | t1    | NULL       | index  | NULL          | PRIMARY | 22      | NULL           |  101 |   100.00 | NULL  |
|  1 | SIMPLE      | t2    | NULL       | eq_ref | PRIMARY       | PRIMARY | 22      | dev.t1.version |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+-------+
2 rows in set, 1 warning (0.00 sec)mysql> explain select *  from person3 t1 left join person4 t2 on t1.version = t2.version order by t2.version;
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+---------------------------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref            | rows | filtered | Extra                           |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+---------------------------------+
|  1 | SIMPLE      | t1    | NULL       | ALL    | NULL          | NULL    | NULL    | NULL           |  101 |   100.00 | Using temporary; Using filesort |
|  1 | SIMPLE      | t2    | NULL       | eq_ref | PRIMARY       | PRIMARY | 22      | dev.t1.version |    1 |   100.00 | NULL                            |
+----+-------------+-------+------------+--------+---------------+---------+---------+----------------+------+----------+---------------------------------+
2 rows in set, 1 warning (0.00 sec)
## 不加where也是一样的。

优化此种情况

mysql> explain select * from person3 t1 left join person4 t2 on t1.version = t2.version join(select version from person3 order by a desc) a_order on t1.version = a_order.version;
+----+-------------+---------+------------+--------+---------------+---------+---------+----------------+------+----------+-------+
| id | select_type | table   | partitions | type   | possible_keys | key     | key_len | ref            | rows | filtered | Extra |
+----+-------------+---------+------------+--------+---------------+---------+---------+----------------+------+----------+-------+
|  1 | SIMPLE      | t1      | NULL       | ALL    | PRIMARY       | NULL    | NULL    | NULL           |  101 |   100.00 | NULL  |
|  1 | SIMPLE      | person3 | NULL       | eq_ref | PRIMARY       | PRIMARY | 22      | dev.t1.version |    1 |   100.00 | NULL  |
|  1 | SIMPLE      | t2      | NULL       | eq_ref | PRIMARY       | PRIMARY | 22      | dev.t1.version |    1 |   100.00 | NULL  |
+----+-------------+---------+------------+--------+---------------+---------+---------+----------------+------+----------+-------+
3 rows in set, 1 warning (0.00 sec)

深入理解MYSQL索引优化:多列索引相关推荐

  1. mysql优化-----多列索引的左前缀规则

    索引优化策略1:索引类型1.1B-tree索引 关注的是:Btree索引的左前缀匹配规则,索引在排序和分组上发挥的作用.注:名叫btree索引,大的方面看都用的二叉树.平衡树.但具体的实现上,各引擎稍 ...

  2. MySQL组合索引(多列索引)使用与优化

    一.多列索引 我们经常听到一些人说"把WHERE条件里的列都加上索引",其实这个建议非常错误.在多个列上建立单独的索引大部分情况下并不能提高MySQL的查询性能.MySQL在5.0 ...

  3. mysql三个字段最优索引_mysql 多列索引优化

    Mysql所有的列都可以使用索引,.对相关列使用索引是提高SELECT操作性能的最佳途径.根据存储引擎定义每个表的最大索引数和最大索引长度.所有存储引擎支持每个表至少16个索引,总索引长度至少256字 ...

  4. 正确理解Mysql的列索引和多列索引

    本文转自:http://blog.csdn.net/lovelyhermione/article/details/4580866 Mysql数据库提供两种类型的索引,如果没正确设置,索引的利用效率会大 ...

  5. mysql聚集索引可以多列吗_MySQL使用单列索引和多列索引

    讨论MySQL选择索引时单列单列索引和多列索引使用,以及多列索引的最左前缀原则. 1. 单列索引 在性能优化过程中,选择在哪些列上创建索引是最重要的步骤之一.可以考虑使用索引的主要有两种类型的列:在W ...

  6. mysql单列索引和多列索引_mysql索引类型 normal, unique, full text

    问题1:mysql索引类型normal,unique,full text的区别是什么? normal:表示普通索引 unique:表示唯一的,不允许重复的索引,如果该字段信息保证不会重复例如身份证号用 ...

  7. MySQL第10天:MySQL索引优化分析之索引介绍

    MySQL索引优化分析之索引简介 1.索引是什么? 2.索引优势.劣势 3.索引分类.基本语法 4.索引结构 5.哪些情况需要创建索引? 6.哪些情况不需要创建索引? ---------------- ...

  8. MySQL联合索引原理_复合索引_组合索引_多列索引

    文章目录 联合索引原理示意图 联合索引就是复合索引.组合索引.多列索引. 联合索引原理示意图

  9. mysql优化十:从架构角度全局理解mysql性能优化

    从架构角度全局理解mysql性能优化 MySQL性能优化其实是个很大的课题,在优化上存在着一个调优金字塔的说法: 很明显从图上可以看出,越往上走,难度越来越高,收益却是越来越小的.比如硬件和 OS调优 ...

  10. Pandas的学习(6.DataFrame和Series创建多层行索引以及多层列索引)

    1.创建多层行索引 (1) 隐式构造         最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组 -- Series也可以创建多层索引 import numpy a ...

最新文章

  1. 操作选项_消防设施操作员关键技能之六:能切换集中火灾报警控制器、消防联动控制器工作状态...
  2. Django框架使用
  3. WebView点击加载的页面中的按钮时不弹出新窗口以及在加载后执行javascript
  4. 无限极业绩_2019中国保健品行业典型企业分析——无限极、康宝莱、汤臣倍健...
  5. 实现Windows Embedded 8 Standard 上的快速开机(HORM)
  6. 企业员工管理系统封面html,单页面模板
  7. php pdo 中dsn参数,PDO连接数据库及DSN详解
  8. (翻译)用户友好的表格的9种设计技巧
  9. python语言是干什么的-python语言可以干什么
  10. 比 Excel 更强大,Python 的可视化库 Altair 入门
  11. 《快学Scala》第二章练习题答案+概述
  12. Typora缩小行间距
  13. 微信小程序开发竟然这么简单?!
  14. Ty-Mysql函数笔记
  15. 第五章-批量数据处理(数组、字符串)代码实例(C++蓝豹子)
  16. Cris 玩转大数据系列之任务流神器 Azkaban
  17. 安卓开发学习之TCP通信
  18. lol体验服一直显示连接服务器,英雄联盟体验服为什么进不去
  19. A component required a bean of type ‘com.wyh.service.XXX‘ that could not be found.
  20. k2677场效应管参数引脚_常用场效MOS应管参数大全-电压参数表图文

热门文章

  1. GridSearch(网格搜索)调参
  2. win server无法安装无线网卡驱动
  3. 学习编程可能会走哪些弯路,有哪些经验可以参考?
  4. mac 自定义 终端 常用快捷指令,加快工作效率
  5. 单片机:电脑通过串口控制LED灯
  6. 深度:怎样打造中老年网红?爆款抖音老年网红的发展模式、现状与机会
  7. 电脑桌面摄像头怎么添加到计算机,笔记本电脑连接摄像头步骤_笔记本电脑怎么连接摄像头-win7之家...
  8. 谈一谈我所遇到的定位属性
  9. 使用FROM装数据而报错出现argument type mismatch的原因
  10. less css 二维,快速开发CSS的利器 - less 嵌套规则