mysql(二) 慢查询分析(一)
2024-09-21 05:17:41
如下表结构:
CREATE TABLE `trade_order` (
`order_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '订单编号',
`total_price` bigint(20) DEFAULT NULL COMMENT '订单总价',
`item_name` varchar(128) DEFAULT NULL COMMENT '商品名称',
`mobile` varchar(16) DEFAULT NULL COMMENT '下单电话',
`gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modify` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=239 DEFAULT CHARSET=utf8mb4;
CREATE TABLE `trade_sub_order` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`order_id` bigint(20) DEFAULT NULL COMMENT '订单号',
`item_price` bigint(20) DEFAULT NULL COMMENT '商品单价',
`item_nums` int(11) DEFAULT NULL COMMENT '商品数量',
`gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modify` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `order_index` (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1227 DEFAULT CHARSET=utf8mb4;
在执行联合查询时,如下2种写法的执行计划有明显差别。
第一种:
select * from trade_order left join `trade_sub_order` using(`order_id`) order by `trade_order`.`order_id` desc;
第二种:
select * from trade_order left join `trade_sub_order` using(`order_id`) order by `trade_sub_order`.`order_id` desc;
两者的差别在于order by的表字段不同。
看执行计划:
第一种的执行计划:
第二种的执行计划:
rows的差别忽略,因为数据在不停的新增过程中。
第一种方式有主键索引,不需要使用临时表。第二种全表扫描,使用临时表,使用文件排序。
这里面的关键问题在于,MySQL 表关联的算法是“Nest Loop Join”,是通过驱动表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后再合并结果(临时表)。
在explain中,第一行出现的表就是驱动表,对于驱动表字段的排序可以直接进行,对于非驱动表字段的排序需要对循环查询的合并结果(临时表)进行排序。所以在第二种写法下就会出现Using temporary。而且由于对非驱动表字段排序,导致将驱动表的全表数据作为驱动表的结果集,产生全表扫描,无法使用到主键索引。
所以,在explain中,有Using temporary时,需要关注是否使用非驱动表字段做排序处理。
驱动表的定义:
在进行多表连接查询时,
- 指定了连接条件,满足查询查询条件的记录数少的表为驱动表;
- 未指定连接条件,行数少的表为驱动表;
最新文章
- 关于移动端常用的盒模型与flex布局
- 纯CSS实现JS效果研究
- [整理]PHP/HTML混写的四种方式
- Linux gcc 编译日记
- PAT乙级 1031. 查验身份证(15) 标志要清零!!!!!!!!!
- XML解析的例子
- 纯js实现div内图片自适应大小
- Unix时代的开创者Ken Thompson
- 安装spark单机环境
- Rotation Proposals
- Category&;nbsp;Protocol&;nbsp;Exte…
- face detection[Multi-view face detection&;&; MTCNN]
- opencv学习笔记(五)
- python-flask-session和scoped_session区别
- Session原理
- BZOJ5099 POI2018Pionek
- Python_oldboy_自动化运维之路(四)
- python requests的使用说明
- ios开发杂项(基础性介绍等)
- Queue模块初识