goods_id
int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘商品id’,
goods_name
varchar(128) NOT NULL DEFAULT ‘’ COMMENT ‘商品名’,
create_time
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
modify_time
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘修改时间’,
PRIMARY KEY (id
),
KEY idx_goods_id
(goods_id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘商品扩展表’;
drop procedure insert_goods_extend_data;
delimiter ;;
create procedure insert_goods_extend_data()
begin declare i int;
declare goods_name CHAR(6);
set i = 1;
while (i <= 100) do
set goods_name = concat(‘商品’,i);
insert into goods_extend (id, goods_id, goods_name) values (i, i, concat(‘商品’,i));
set i=i+1;
end while;
end;;
delimiter ;
call insert_goods_extend_data();
执行过程分析
有了上面的数据,我们就可以对 join 命令的执行过程进行分析了。
一般情况下,我们查看 MYSQL 执行过程都是通过 explain,explain 提供了 MYSQL 如何执行查询语句的信息。
为了更直观的展示,我们使用 straight_join
强制使用 goods_extend 表作为驱动表。
mysql> explain select * from goods_extend straight_join goods on goods.goods_id = goods_extend.goods_id;
±—±------------±-------------±-----------±-----±--------------±-------------±--------±-------------------------------±-----±---------±------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
±—±------------±-------------±-----------±-----±--------------±-------------±--------±-------------------------------±-----±---------±------+
| 1 | SIMPLE | goods_extend | NULL | ALL | idx_goods_id | NULL | NULL | NULL | 100 | 100.00 | NULL |
| 1 | SIMPLE | goods | NULL | ref | idx_goods_id | idx_goods_id | 4 | example2.goods_extend.goods_id | 1 | 100.00 | NULL |
±—±------------±-------------±-----------±-----±--------------±-------------±--------±-------------------------------±-----±---------±------+
2 rows in set, 1 warning (0.00 sec)
从上面可以看出,驱动表 goods_extend
查询的是全表,被驱动表 goods
的查询类型为 ref
,之前我们有在 mysql explain 详解 讲过,type
为 ref
的情形是 join 连接,命中 普通索引
。从上面的语句我们还可以看到,goods 表扫描的行数为 1,这也正好对应着 ref
的 等值连接
特性,说明是一行一行查询的。
因此,这条查询语句的执行过程是这样的:
- 从表 goods_extend 中读取一行数据 R;
- 从数据行 R 中取出字段 goods_id 并到 goods 表里去查找。
- 取出表 goods 表中满足条件的行,和 R 组成一行,作为结果集的一部分;
- 重复执行步骤 1 到 3,直到表 goods_extend 的末尾循环结束。
这个过程是先遍历表 goods_extend,然后根据从表 goods_extend 中取出的每行数据中的 goods_id 值ÿ