索引 - Explain

2018-09-07  本文已影响7人  诺之林

本文的示例代码参考index_explain

目录

startup

vim user_info.sql
CREATE TABLE `user_info` (
  `id`   BIGINT(20)  NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(50) NOT NULL DEFAULT '',
  `age`  INT(11)              DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `name_index` (`name`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

INSERT INTO user_info (name, age) VALUES ('xys', 20);
INSERT INTO user_info (name, age) VALUES ('a', 21);
INSERT INTO user_info (name, age) VALUES ('b', 23);
INSERT INTO user_info (name, age) VALUES ('c', 50);
INSERT INTO user_info (name, age) VALUES ('d', 15);
INSERT INTO user_info (name, age) VALUES ('e', 20);
INSERT INTO user_info (name, age) VALUES ('f', 21);
INSERT INTO user_info (name, age) VALUES ('g', 23);
INSERT INTO user_info (name, age) VALUES ('h', 50);
INSERT INTO user_info (name, age) VALUES ('i', 15);
vim order_info.sql
CREATE TABLE `order_info` (
  `id`           BIGINT(20)  NOT NULL AUTO_INCREMENT,
  `user_id`      BIGINT(20)           DEFAULT NULL,
  `product_name` VARCHAR(50) NOT NULL DEFAULT '',
  `productor`    VARCHAR(30)          DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `user_product_detail_index` (`user_id`, `product_name`, `productor`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

INSERT INTO order_info (user_id, product_name, productor) VALUES (1, 'p1', 'WHH');
INSERT INTO order_info (user_id, product_name, productor) VALUES (1, 'p2', 'WL');
INSERT INTO order_info (user_id, product_name, productor) VALUES (1, 'p1', 'DX');
INSERT INTO order_info (user_id, product_name, productor) VALUES (2, 'p1', 'WHH');
INSERT INTO order_info (user_id, product_name, productor) VALUES (2, 'p5', 'WL');
INSERT INTO order_info (user_id, product_name, productor) VALUES (3, 'p3', 'MA');
INSERT INTO order_info (user_id, product_name, productor) VALUES (4, 'p1', 'WHH');
INSERT INTO order_info (user_id, product_name, productor) VALUES (6, 'p1', 'WHH');
INSERT INTO order_info (user_id, product_name, productor) VALUES (9, 'p8', 'TE');
mycli -uroot -p123456
DROP DATABASE IF EXISTS `explain`;
CREATE DATABASE IF NOT EXISTS `explain`;
USE explain;

source ./user_info.sql;
source ./order_info.sql;

explain

EXPLAIN (SELECT * FROM user_info WHERE id = 2);
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+--------+
| id | select_type | table     | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra  |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+--------+
| 1  | SIMPLE      | user_info | <null>     | const | PRIMARY       | PRIMARY | 8       | const | 1    | 100.0    | <null> |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+--------+

select_type

EXPLAIN (SELECT * FROM user_info  WHERE id IN (1, 2, 3))
UNION
(SELECT * FROM user_info WHERE id IN (3, 4, 5));
+--------+--------------+------------+------------+-------+---------------+---------+---------+--------+--------+----------+-----------------+
| id     | select_type  | table      | partitions | type  | possible_keys | key     | key_len | ref    | rows   | filtered | Extra           |
+--------+--------------+------------+------------+-------+---------------+---------+---------+--------+--------+----------+-----------------+
| 1      | PRIMARY      | user_info  | <null>     | range | PRIMARY       | PRIMARY | 8       | <null> | 3      | 100.0    | Using where     |
| 2      | UNION        | user_info  | <null>     | range | PRIMARY       | PRIMARY | 8       | <null> | 3      | 100.0    | Using where     |
| <null> | UNION RESULT | <union1,2> | <null>     | ALL   | <null>        | <null>  | <null>  | <null> | <null> | <null>   | Using temporary |
+--------+--------------+------------+------------+-------+---------------+---------+---------+--------+--------+----------+-----------------+

什么叫索引回表查询数据? 即先找到索引 再通过索引找到数据所在位置

聚簇索引

数据访问速度更快 因为索引和数据存储在一起
插入更新代价更高 因为索引和数据存储在一起

覆盖索引

EXPLAIN (SELECT id FROM user_info  WHERE id IN (1, 2, 3));
+----+-------------+-----------+------------+-------+---------------+------------+---------+--------+------+----------+--------------------------+
| id | select_type | table     | partitions | type  | possible_keys | key        | key_len | ref    | rows | filtered | Extra                    |
+----+-------------+-----------+------------+-------+---------------+------------+---------+--------+------+----------+--------------------------+
| 1  | SIMPLE      | user_info | <null>     | index | PRIMARY       | name_index | 152     | <null> | 10   | 30.0     | Using where; Using index |
+----+-------------+-----------+------------+-------+---------------+------------+---------+--------+------+----------+--------------------------+

type

EXPLAIN (SELECT * FROM user_info, order_info WHERE user_info.id = order_info.user_id);
+----+-------------+------------+------------+--------+---------------------------+---------------------------+---------+----------------------------+------+----------+--------------------------+
| id | select_type | table      | partitions | type   | possible_keys             | key                       | key_len | ref                        | rows | filtered | Extra                    |
+----+-------------+------------+------------+--------+---------------------------+---------------------------+---------+----------------------------+------+----------+--------------------------+
| 1  | SIMPLE      | order_info | <null>     | index  | user_product_detail_index | user_product_detail_index | 254     | <null>                     | 9    | 100.0    | Using where; Using index |
| 1  | SIMPLE      | user_info  | <null>     | eq_ref | PRIMARY                   | PRIMARY                   | 8       | explain.order_info.user_id | 1    | 100.0    | <null>                   |
+----+-------------+------------+------------+--------+---------------------------+---------------------------+---------+----------------------------+------+----------+--------------------------+

唯一索引

主键索引

key_len

EXPLAIN (SELECT * FROM order_info WHERE user_id < 3 AND product_name = 'p1' AND productor = 'WHH');
+----+-------------+------------+------------+-------+---------------------------+---------------------------+---------+--------+------+----------+--------------------------+
| id | select_type | table      | partitions | type  | possible_keys             | key                       | key_len | ref    | rows | filtered | Extra                    |
+----+-------------+------------+------------+-------+---------------------------+---------------------------+---------+--------+------+----------+--------------------------+
| 1  | SIMPLE      | order_info | <null>     | range | user_product_detail_index | user_product_detail_index | 9       | <null> | 5    | 11.11    | Using where; Using index |
+----+-------------+------------+------------+-------+---------------------------+---------------------------+---------+--------+------+----------+--------------------------+

根据最左前缀匹配原则 查询仅仅使用到了联合索引的user_id字段 因此效率并不高

联合索引

EXPLAIN (SELECT * FROM order_info WHERE user_id = 1 AND product_name = 'p1');
+----+-------------+------------+------------+------+---------------------------+---------------------------+---------+-------------+------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys             | key                       | key_len | ref         | rows | filtered | Extra       |
+----+-------------+------------+------------+------+---------------------------+---------------------------+---------+-------------+------+----------+-------------+
| 1  | SIMPLE      | order_info | <null>     | ref  | user_product_detail_index | user_product_detail_index | 161     | const,const | 2    | 100.0    | Using index |
+----+-------------+------------+------------+------+---------------------------+---------------------------+---------+-------------+------+----------+-------------+

前缀索引

索引更小查询更快
不能在ORDER BY或GROUP BY中使用前缀索引

不能把前缀索引用作覆盖索引

参考

上一篇下一篇

猜你喜欢

热点阅读