zoukankan      html  css  js  c++  java
  • MySQL索引实战 & 执行计划

    一、执行计划(只是自己理解)

    1,id):
    id 相同,执行顺序由上到下,按照我的理解,通常发生于子查询;
    id 不同,如果是子查询,id的序号会递增,id越大则优先级越高,越先会被执行;
    id 既不同又相同,id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行;

    2,select_type):
    simple:简单的select查询,查询中不包含子查询或者union;
    primary:查询中包含任何复杂的子部分,最外层查询则被标记为primary;
    subquery:在select 或 where列表中(除了from字句中包含的子查询外)包含了子查询,可能是subquery;
    derived:表示用了临时表;
    union result:从union表获取结果的select;

    3,table):
    显示的查询表名,如果查询使用了别名,那么这里显示的是别名;
    如果不涉及对数据表的操作,那么这显示为null;
    如果显示为尖括号括起来的<derived N>就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生;
    如果是尖括号括起来的<union M,N>,与<derived N>类似,也是一个临时表,表示这个结果来自于union查询的id为M,N的结果集;

    4,type)访问数据的方式:
    system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
    system:可以忽略不计;
    const:使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const;
    eq_ref:看不懂;
    ref:普通的索引扫描方式;
    all:这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录。
    possible_keys:查询可能使用到的索引都会在这里列出来;如果为NULL,说明没有WHERE条件时查询优化器无法通过索引检索数据。
    key:查询真正使用到的索引,select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。
    rows:这里是执行计划中估算的扫描行数,不是精确值。
    extra:这个列可以显示的信息非常多,有几十种,常用的有:
        using filesort:排序时无法使用到索引时,就会出现这个。常见于order by和group by语句中。
        using index:查询时不需要回表查询,直接通过索引就可以获取查询的数据(表明使用了覆盖索引)。
        Using index condition, Using where; 用了索引,但是需要回表查找;(目前我的理解是这样)

    二、实战

    基本哦:

    SHOW INDEX FROM test_emp;
    +----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table    | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | test_emp |          0 | PRIMARY      |            1 | id          | A         |           3 |     NULL | NULL   |      | BTREE      |         |               |
    | test_emp |          1 | idx_age_name |            1 | age         | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
    | test_emp |          1 | idx_age_name |            2 | name        | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
    +----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    rows in set (0.00 sec)
    
    // 使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const;
    mysql> EXPLAIN SELECT * FROM test_emp WHERE id = '2';
    +----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
    | id | select_type | table    | type  | possible_keys | key     | key_len | ref   | rows | Extra |
    +----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
    |  1 | SIMPLE      | test_emp | const | PRIMARY       | PRIMARY | 4       | const |    1 | NULL  |
    +----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
    row in set (0.01 sec)
    
    // type 为 ref,说明用了普通的索引扫描方式
    // Using index condition, Using where; 用了索引,但是需要回表查找;(目前我的理解是这样)
    mysql> EXPLAIN SELECT * FROM test_emp WHERE age = '22' AND `name` = '111';
    +----+-------------+----------+------+---------------+--------------+---------+-------------+------+-----------------------+
    | id | select_type | table    | type | possible_keys | key          | key_len | ref         | rows | Extra                 |
    +----+-------------+----------+------+---------------+--------------+---------+-------------+------+-----------------------+
    |  1 | SIMPLE      | test_emp | ref  | idx_age_name  | idx_age_name | 773     | const,const |    1 | Using index condition |
    +----+-------------+----------+------+---------------+--------------+---------+-------------+------+-----------------------+
    row in set (0.00 sec)
    
    // 说明如果都是等号的话,顺序是没有问题的
    mysql> EXPLAIN SELECT * FROM test_emp WHERE `name` = '111' AND age = '22';
    +----+-------------+----------+------+---------------+--------------+---------+-------------+------+-----------------------+
    | id | select_type | table    | type | possible_keys | key          | key_len | ref         | rows | Extra                 |
    +----+-------------+----------+------+---------------+--------------+---------+-------------+------+-----------------------+
    |  1 | SIMPLE      | test_emp | ref  | idx_age_name  | idx_age_name | 773     | const,const |    1 | Using index condition |
    +----+-------------+----------+------+---------------+--------------+---------+-------------+------+-----------------------+
    row in set (0.00 sec)
    
    // 好像这个也没有问题
    mysql> EXPLAIN SELECT * FROM test_emp WHERE age = '22';
    +----+-------------+----------+------+---------------+--------------+---------+-------+------+-------+
    | id | select_type | table    | type | possible_keys | key          | key_len | ref   | rows | Extra |
    +----+-------------+----------+------+---------------+--------------+---------+-------+------+-------+
    |  1 | SIMPLE      | test_emp | ref  | idx_age_name  | idx_age_name | 5       | const |    1 | NULL  |
    +----+-------------+----------+------+---------------+--------------+---------+-------+------+-------+
    row in set (0.00 sec)
    
    // 这个就没有办法了,因为age在前面
    mysql> EXPLAIN SELECT * FROM test_emp WHERE `name` = '111';
    +----+-------------+----------+------+---------------+------+---------+------+------+-------------+
    | id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows | Extra       |
    +----+-------------+----------+------+---------------+------+---------+------+------+-------------+
    |  1 | SIMPLE      | test_emp | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where |
    +----+-------------+----------+------+---------------+------+---------+------+------+-------------+
    row in set (0.00 sec)
    
    // age和name反了
    mysql> EXPLAIN SELECT * FROM test_emp WHERE `name` = '111' ORDER BY age;
    +----+-------------+----------+------+---------------+------+---------+------+------+-----------------------------+
    | id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows | Extra                       |
    +----+-------------+----------+------+---------------+------+---------+------+------+-----------------------------+
    |  1 | SIMPLE      | test_emp | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where; Using filesort |
    +----+-------------+----------+------+---------------+------+---------+------+------+-----------------------------+
    row in set (0.00 sec)
    
    // 顺序顺序,age在前,name在后
    mysql> EXPLAIN SELECT * FROM test_emp WHERE `age` = '111' ORDER BY `name`;
    +----+-------------+----------+------+---------------+--------------+---------+-------+------+-------------+
    | id | select_type | table    | type | possible_keys | key          | key_len | ref   | rows | Extra       |
    +----+-------------+----------+------+---------------+--------------+---------+-------+------+-------------+
    |  1 | SIMPLE      | test_emp | ref  | idx_age_name  | idx_age_name | 5       | const |    1 | Using where |
    +----+-------------+----------+------+---------------+--------------+---------+-------+------+-------------+
    row in set (0.00 sec)
    
    // 顺序顺序,age在前,name在后
    mysql> EXPLAIN SELECT * FROM test_emp GROUP BY age ORDER BY `name`;
    +----+-------------+----------+-------+---------------+--------------+---------+------+------+---------------------------------+
    | id | select_type | table    | type  | possible_keys | key          | key_len | ref  | rows | Extra                           |
    +----+-------------+----------+-------+---------------+--------------+---------+------+------+---------------------------------+
    |  1 | SIMPLE      | test_emp | index | idx_age_name  | idx_age_name | 773     | NULL |    3 | Using temporary; Using filesort |
    +----+-------------+----------+-------+---------------+--------------+---------+------+------+---------------------------------+
    row in set (0.00 sec)
    View Code

     id当然为主键,其外就建立了一个联合索引(注意,联合索引的顺序很重要,很重要)

    mysql> SHOW INDEX FROM test_person;
    +-------------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table       | Non_unique | Key_name      | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +-------------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | test_person |          0 | PRIMARY       |            1 | id          | A         |           3 |     NULL | NULL   |      | BTREE      |         |               |
    | test_person |          1 | idx_age_birth |            1 | age         | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
    | test_person |          1 | idx_age_birth |            2 | birthday    | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
    +-------------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    3 rows in set (0.00 sec)
    View Code

     例子一,注意order by 后面的以及extra下面的,在这里where后面的条件不变:

    mysql> explain select * from test_person where age > 20 order by age;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                    |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    |  1 | SIMPLE      | test_person | index | idx_age_birth | idx_age_birth | 11      | NULL |    3 | Using where; Using index |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    1 row in set (0.01 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person WHERE age > 20 ORDER BY age,birthday;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                    |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    |  1 | SIMPLE      | test_person | index | idx_age_birth | idx_age_birth | 11      | NULL |    3 | Using where; Using index |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    1 row in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person WHERE age > 20 ORDER BY birthday;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                                    |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    |  1 | SIMPLE      | test_person | index | idx_age_birth | idx_age_birth | 11      | NULL |    3 | Using where; Using index; Using filesort |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    1 row in set (0.01 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person WHERE age > 20 ORDER BY birthday,age;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                                    |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    |  1 | SIMPLE      | test_person | index | idx_age_birth | idx_age_birth | 11      | NULL |    3 | Using where; Using index; Using filesort |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    1 row in set (0.00 sec)
    View Code

     例子二,注意order by 后面的以及extra下面的,在这里where后面的条件不变:

    mysql> EXPLAIN SELECT * FROM test_person WHERE birthday > '2012-12-12 00:00:00' ORDER BY age;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                    |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    |  1 | SIMPLE      | test_person | index | NULL          | idx_age_birth | 11      | NULL |    3 | Using where; Using index |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    1 row in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person WHERE birthday > '2012-12-12 00:00:00' ORDER BY age,birthday;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                    |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    |  1 | SIMPLE      | test_person | index | NULL          | idx_age_birth | 11      | NULL |    3 | Using where; Using index |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+--------------------------+
    1 row in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person WHERE birthday > '2012-12-12 00:00:00' ORDER BY birthday;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                                    |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    |  1 | SIMPLE      | test_person | index | NULL          | idx_age_birth | 11      | NULL |    3 | Using where; Using index; Using filesort |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    1 row in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person WHERE birthday > '2012-12-12 00:00:00' ORDER BY birthday,age;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                                    |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    |  1 | SIMPLE      | test_person | index | NULL          | idx_age_birth | 11      | NULL |    3 | Using where; Using index; Using filesort |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+------------------------------------------+
    1 row in set (0.00 sec)
    View Code

    例子三,这里得出的结论是,要不就得是同时升序,要不就得是同时降序啊,否则用不到索引:

    mysql> EXPLAIN SELECT * FROM test_person ORDER BY age DESC;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra       |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-------------+
    |  1 | SIMPLE      | test_person | index | NULL          | idx_age_birth | 11      | NULL |    3 | Using index |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-------------+
    1 row in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person ORDER BY birthday DESC;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                       |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    |  1 | SIMPLE      | test_person | index | NULL          | idx_age_birth | 11      | NULL |    3 | Using index; Using filesort |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    1 row in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person ORDER BY age ASC, birthday DESC;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                       |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    |  1 | SIMPLE      | test_person | index | NULL          | idx_age_birth | 11      | NULL |    3 | Using index; Using filesort |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    1 row in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person ORDER BY age DESC, birthday DESC;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra       |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-------------+
    |  1 | SIMPLE      | test_person | index | NULL          | idx_age_birth | 11      | NULL |    3 | Using index |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-------------+
    1 row in set (0.00 sec)
    View Code

    例子四:

    mysql> EXPLAIN SELECT * FROM test_person ORDER BY id;
    +----+-------------+-------------+-------+---------------+---------+---------+------+------+-------+
    | id | select_type | table       | type  | possible_keys | key     | key_len | ref  | rows | Extra |
    +----+-------------+-------------+-------+---------------+---------+---------+------+------+-------+
    |  1 | SIMPLE      | test_person | index | NULL          | PRIMARY | 4       | NULL |    3 | NULL  |
    +----+-------------+-------------+-------+---------------+---------+---------+------+------+-------+
    1 row in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person ORDER BY id,birthday;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                       |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    |  1 | SIMPLE      | test_person | index | NULL          | idx_age_birth | 11      | NULL |    3 | Using index; Using filesort |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    1 row in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person ORDER BY id,age;
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    | id | select_type | table       | type  | possible_keys | key           | key_len | ref  | rows | Extra                       |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    |  1 | SIMPLE      | test_person | index | NULL          | idx_age_birth | 11      | NULL |    3 | Using index; Using filesort |
    +----+-------------+-------------+-------+---------------+---------------+---------+------+------+-----------------------------+
    1 row in set (0.01 sec)
    View Code

    三、结论:

    1order by子句,尽量使用Index方式排序,在索引列上遵循索引的最佳左前缀原则。 复合(联合)索引形如 key (‘A1’,’A2’,’A3’ ),排序的思路一般是:
      先按照A1来排序,A1相同,然后按照A2排序,以此类推,这样对于(A1),(A1,A2), (A1,A2,A3)的索引都是有效的,但是对于(A2,A3)这样的索引就无效了。尽量避免因索引字段的缺失 或 索引字段顺序的不同 引起的FileSort排序。
    2)mysql一次查询只能使用一个索引。如果要对多个字段使用索引,建立复合索引。 ORDER BY 能使用索引最左前缀:
           - ORDER BY a
         - ORDER BY a,b
           - ORDER BY a,b,c
           - ORDER BY a DESC,b DESC,c DESC
       如果 WHERE 使用索引的最左前缀为常量,则 ORDER BY能使用索引:
        - WHERE a = const ORDER BY b,c
        - WHERE a = const AND b = const ORDER BY c
        - WHERE a = const AND b > const ORDER BY b,c
     (请看下面的例子) 不能使用索引进行排序:
        - order by a asc, b desc, c desc (排序不一致嘛)
        - where g = const order by b,c (丢失a索引)
        - where a = const order by c (丢失b索引)
        - where a = const order by a,d (d不是索引的一部分)
        - where a in(...) order by b,c (对于排序来说,多个相等的条件也是范围查询)
        - 如果a,b分别建立了一个索引(不是普通索引,而是联合索引),对于这样的排序 order by a,b 是不会走索引
        - 如果查询条件为函数,也无法使用索引

    例子一:

    mysql> SHOW INDEX FROM test_person;
    +-------------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table       | Non_unique | Key_name      | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +-------------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | test_person |          0 | PRIMARY       |            1 | id          | A         |           3 |     NULL | NULL   |      | BTREE      |         |               |
    | test_person |          1 | idx_age_birth |            1 | age         | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
    | test_person |          1 | idx_age_birth |            2 | name        | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
    | test_person |          1 | idx_age_birth |            3 | birthday    | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
    +-------------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    rows in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person WHERE age = 1 AND name > 22 ORDER BY name,birthday;
    +----+-------------+-------------+------+---------------+---------------+---------+-------+------+--------------------------+
    | id | select_type | table       | type | possible_keys | key           | key_len | ref   | rows | Extra                    |
    +----+-------------+-------------+------+---------------+---------------+---------+-------+------+--------------------------+
    |  1 | SIMPLE      | test_person | ref  | idx_age_birth | idx_age_birth | 5       | const |    1 | Using where; Using index |
    +----+-------------+-------------+------+---------------+---------------+---------+-------+------+--------------------------+
    row in set (0.01 sec)
    View Code

     例子二:

    mysql> SHOW INDEX FROM test_person;
    +-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table       | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | test_person |          0 | PRIMARY  |            1 | id          | A         |           3 |     NULL | NULL   |      | BTREE      |         |               |
    | test_person |          1 | idx_age  |            1 | age         | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
    | test_person |          1 | idx_name |            1 | name        | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
    +-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    rows in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person ORDER BY age,name;
    +----+-------------+-------------+------+---------------+------+---------+------+------+----------------+
    | id | select_type | table       | type | possible_keys | key  | key_len | ref  | rows | Extra          |
    +----+-------------+-------------+------+---------------+------+---------+------+------+----------------+
    |  1 | SIMPLE      | test_person | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using filesort |
    +----+-------------+-------------+------+---------------+------+---------+------+------+----------------+
    row in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person WHERE age = 22 ORDER BY age;
    +----+-------------+-------------+------+---------------+---------+---------+-------+------+-------+
    | id | select_type | table       | type | possible_keys | key     | key_len | ref   | rows | Extra |
    +----+-------------+-------------+------+---------------+---------+---------+-------+------+-------+
    |  1 | SIMPLE      | test_person | ref  | idx_age       | idx_age | 5       | const |    1 | NULL  |
    +----+-------------+-------------+------+---------------+---------+---------+-------+------+-------+
    row in set (0.00 sec)
    
    mysql> EXPLAIN SELECT * FROM test_person WHERE age = 22 ORDER BY name;
    +----+-------------+-------------+------+---------------+---------+---------+-------+------+-----------------------------+
    | id | select_type | table       | type | possible_keys | key     | key_len | ref   | rows | Extra                       |
    +----+-------------+-------------+------+---------------+---------+---------+-------+------+-----------------------------+
    |  1 | SIMPLE      | test_person | ref  | idx_age       | idx_age | 5       | const |    1 | Using where; Using filesort |
    +----+-------------+-------------+------+---------------+---------+---------+-------+------+-----------------------------+
    row in set (0.01 sec)
    mysql> EXPLAIN SELECT * FROM test_person WHERE birthday = NOW() ORDER BY name;
    +----+-------------+-------------+------+---------------+------+---------+------+------+-----------------------------+
    | id | select_type | table       | type | possible_keys | key  | key_len | ref  | rows | Extra                       |
    +----+-------------+-------------+------+---------------+------+---------+------+------+-----------------------------+
    |  1 | SIMPLE      | test_person | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where; Using filesort |
    +----+-------------+-------------+------+---------------+------+---------+------+------+-----------------------------+
    row in set (0.01 sec)
    View Code

    group by与order by的索引优化基本一样,group by实质是先排序后分组,也就是分组之前必排序,遵照索引的最佳左前缀原则可以大大提高group by的效率。

  • 相关阅读:
    二分查找
    基本功能
    pandas的数据结构
    部署metrics-server遇到的坑
    Promethus安装指南
    Spark学习笔记
    Hadoop学习笔记
    大数据处理框架
    大数据Hadoop生态圈:Pig和Hive
    Hadoop HA 机制学习
  • 原文地址:https://www.cnblogs.com/ericguoxiaofeng/p/8638912.html
Copyright © 2011-2022 走看看