MySQL多表连接过程中自动创建索引一例:
2017-03-13 19:01
423 查看
一 创建表如下 CREATE TABLE t1 (id INT PRIMARY KEY, a INT UNIQUE,
b INT, c INT, e INT, KEY bc (b, c));
INSERT INTO t1 VALUES (0, 0, NULL, 0, 0), (1, 1, 1, 1, 1), (2, 2, 1, 2, 2),
(3, 3, 1, 1, 3), (6, 6, 1, 1, 6),
(7, 7, 2, 2, 7), (8, 8, 3, 3, 8), (9, 9, 4, 5, NULL);
CREATE TABLE t2 (id INT PRIMARY KEY, a INT UNIQUE,
b INT, c INT, e INT, KEY bc (b, c));
INSERT INTO t2 VALUES (0, 0, NULL, 0, 0), (1, 1, 1, 1, 1), (2, 2, 1, 2, 2),
(3, 3, 1, 1, 3), (4, 4, 2, 1, 4), (5, 5, 2, 2, 5), (6, 6, 1, 1, 6),
(7, 7, 2, 2, 7), (8, 8, 3, 3, 8), (9, 9, 4, 5, NULL);
CREATE TABLE t3 (id INT PRIMARY KEY, a INT UNIQUE,
b INT, c INT, e INT, KEY bc (b, c));
INSERT INTO t3 VALUES (0, 0, NULL, 0, 0), (1, 1, 1, 1, 1), (2, 2, 1, 2, 2),
(3, 3, 1, 1, 3), (4, 4, 2, 1, 4), (5, 5, 2, 2, 5), (6, 6, 1, 1, 6),
(8, 8, 3, 3, 8), (9, 9, 4, 5, NULL);
二 执行查询如下 mysql> explain SELECT * FROM t1 WHERE e IN (SELECT e FROM t2 WHERE c IN (SELECT c FROM t3));
+----+--------------+-------------+------------+--------+---------------+------------+---------+-----------+------+----------+------------------------
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra
+----+--------------+-------------+------------+--------+---------------+------------+---------+-----------+------+----------+------------------------
| 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 8 | 100.00 | Using where
| 1 | SIMPLE | <subquery2> | NULL | eq_ref | <auto_key> | <auto_key> | 5 | test.t1.e | 1 | 100.00 | NULL
| 2 | MATERIALIZED | t3 | NULL | index | NULL | bc | 10 | NULL | 9 | 100.00 | Using index
| 2 | MATERIALIZED | t2 | NULL | ALL | NULL | NULL | NULL | NULL | 10 | 10.00 | Using where; Using join buffer (Block Nested Loop) |
+----+--------------+-------------+------------+--------+---------------+------------+---------+-----------+------+----------+------------------------
4 rows in set, 1 warning (0.10 sec)三 分析
1 t2和t3被物化,这是一个优化点
2 物化了的t2和t3做了一个join操作,结果是一个子查询‘<subquery2>’的一部分
3 对于<subquery2>子查询,“type”列的值,是eq_ref, 通常主键才有此值(唯一键只能用到ref)。 这是因为MySQL提供了另外的优化点,即:
对于物化的对象,可以为其自动创建索引,这表现在了“possible_keys” 的值为 ‘<auto_key>’上。
b INT, c INT, e INT, KEY bc (b, c));
INSERT INTO t1 VALUES (0, 0, NULL, 0, 0), (1, 1, 1, 1, 1), (2, 2, 1, 2, 2),
(3, 3, 1, 1, 3), (6, 6, 1, 1, 6),
(7, 7, 2, 2, 7), (8, 8, 3, 3, 8), (9, 9, 4, 5, NULL);
CREATE TABLE t2 (id INT PRIMARY KEY, a INT UNIQUE,
b INT, c INT, e INT, KEY bc (b, c));
INSERT INTO t2 VALUES (0, 0, NULL, 0, 0), (1, 1, 1, 1, 1), (2, 2, 1, 2, 2),
(3, 3, 1, 1, 3), (4, 4, 2, 1, 4), (5, 5, 2, 2, 5), (6, 6, 1, 1, 6),
(7, 7, 2, 2, 7), (8, 8, 3, 3, 8), (9, 9, 4, 5, NULL);
CREATE TABLE t3 (id INT PRIMARY KEY, a INT UNIQUE,
b INT, c INT, e INT, KEY bc (b, c));
INSERT INTO t3 VALUES (0, 0, NULL, 0, 0), (1, 1, 1, 1, 1), (2, 2, 1, 2, 2),
(3, 3, 1, 1, 3), (4, 4, 2, 1, 4), (5, 5, 2, 2, 5), (6, 6, 1, 1, 6),
(8, 8, 3, 3, 8), (9, 9, 4, 5, NULL);
二 执行查询如下 mysql> explain SELECT * FROM t1 WHERE e IN (SELECT e FROM t2 WHERE c IN (SELECT c FROM t3));
+----+--------------+-------------+------------+--------+---------------+------------+---------+-----------+------+----------+------------------------
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra
+----+--------------+-------------+------------+--------+---------------+------------+---------+-----------+------+----------+------------------------
| 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 8 | 100.00 | Using where
| 1 | SIMPLE | <subquery2> | NULL | eq_ref | <auto_key> | <auto_key> | 5 | test.t1.e | 1 | 100.00 | NULL
| 2 | MATERIALIZED | t3 | NULL | index | NULL | bc | 10 | NULL | 9 | 100.00 | Using index
| 2 | MATERIALIZED | t2 | NULL | ALL | NULL | NULL | NULL | NULL | 10 | 10.00 | Using where; Using join buffer (Block Nested Loop) |
+----+--------------+-------------+------------+--------+---------------+------------+---------+-----------+------+----------+------------------------
4 rows in set, 1 warning (0.10 sec)三 分析
1 t2和t3被物化,这是一个优化点
2 物化了的t2和t3做了一个join操作,结果是一个子查询‘<subquery2>’的一部分
3 对于<subquery2>子查询,“type”列的值,是eq_ref, 通常主键才有此值(唯一键只能用到ref)。 这是因为MySQL提供了另外的优化点,即:
对于物化的对象,可以为其自动创建索引,这表现在了“possible_keys” 的值为 ‘<auto_key>’上。
相关文章推荐
- Python+Django连接mysql 自动创建model
- linux下实现shell脚本自动连接mongodb数据库并创建索引
- hibernate4连接mysql自动创建表之错误
- hibernate4连接mysql自动创建表之错误
- KETTLE整库迁移方案(SQL server迁移至Mysql,迁移过程自动创建表结构)
- 超详细教你怎么连接SAE mysql (有创建表的过程)
- mongo 自动创建索引导致应用连接超时
- mybatis generator自动创建代码连接mysql6.0+问题
- mysql创建索引以及进程过程中出现的问题
- hibernate4连接mysql自动创建表失败
- hibernate4连接mysql自动创建表之错误
- mysql给创建的外键自动建立索引吗?
- MySQL查询优化一例---自动利用索引进行优化
- SQL Server如何识别真实和自动创建的索引
- Lucene 源代码剖析-9 索引创建过程
- 存储过程中调用 连接服务器中创建的外部服务器连接 “异类查询要求为连接设置 ANSI_NULLS 和 ANSI_WARNINGS 选项” 的解决办法
- 生成索引信息及自动创建脚本(Sql Server 2000)
- 解决数据库连接池连接mysql时,每隔8小时mysql自动断开所有连接的问题
- 如何识别真实和自动创建的索引?
- 利用vc远程连接mysql一例