现有两个表
(相关资料图)
create table Orders ( id integer AUTO_INCREMENT PRIMARY KEY, name varchar(255) not null, order_date datetime NOT NULL ) comment "订单表"; create table OrderDetails ( id integer AUTO_INCREMENT PRIMARY KEY, order_id integer not null, product_code varchar(20) not null, quantity integer not null ) comment "订单详情表";
子查询
select * from orders where id in (select order_id from OrderDetails where product_code = "PC50")
;
优化1:改为表连接
select * from orders as t1 inner join orderdetails o on t1.id = o.order_id where product_code="PC50"
;
优化2:给 order_id
字段添加索引
优化3:给 product_code
字段添加索引
结果证明:给 product_code
字段添加索引 的效果优于给 order_id
字段添加索引,因为不用对索引列进行全表扫描
优化4:给order_id 和 product_code
添加复合索引
优化5:给product_code 和 order_id
添加复合索引
对于复合索引 idx(order_id, product_code)
,因为查询中需要判断 product_code
的值是否为 PC51,所以要对 order_id
该列进行全索引扫描,性能较低 [ 因为 product_code 不是有序的,先根据 order_id 进行排序,再根据 product_code 进行排序 ];
对于复合索引 idx(product_code, order_id)
,因为 product_code
本身是有序的,所以可以快速定位到该 product_code
然后快速获取该 order_id
,性能较高;
现有一个电影表
create table film ( id integer auto_increment primary key, score decimal(2, 1) not null, release_date date not null, film_name varchar(255) not null, introduction varchar(255) not null ) comment "电影表";
对于浅分页
select score, release_date, film_name from film order by score limit 0, 20;
耗时 825ms
对于深分页
select score, release_date, film_name, introduction from film order by score limit 1500000, 20;
耗时 1s 247ms
若不加处理,浅分页的速度快,limit 的深度越深,查询的效率越慢
给 score 字段添加索引
create index idx_score on film(score);
结果
浅分页的速度为 60 ms,深分页的速度为 1s 134ms
浅分页的情况得到了优化,而深分页依然很慢
查看深分页的执行情况
其并没有走 score 索引,走的是全表的扫描,所以给排序字段添加索引只能优化浅分页的情况
解释
只给 score 添加索引,会造成回表的情况
对于浅分页,回表的性能消耗小于全表扫描,故走 score 索引;
对于深分页,回表的性能消耗大于全表扫描,故走 全表扫描;
给 score, release_date, film_name 添加复合索引
create index idx_score_date_name on film(score, release_date, film_name);
浅分页的速度为 58 ms,深分页的速度为 357 ms,两者的速度都得到了提升
查看深分页的执行情况
可见其走了复合索引
解释
对于该复合索引,排序的值和查询的值都在索引上,没有进行回表的操作,效率很高。唯一的不足是:若要添加新的查询列,就要更改该索引的列,不够灵活。
改进SQL语句,给 score 字段添加索引
# 给排序字段添加索引 + 手动回表 select score, release_date, film_name,introduction from film a join (select id from film order by score limit 1500000, 20) b on a.id = b.id;
思路:先把 limit 字段的 id 找出来,这里走了 score 索引,效率高。然后再走主键索引根据 id 去寻找;
该语句的执行情况
可见子查询中走了 score 索引,而外查询走了主键索引,效率非常高,执行速度为 297 ms
缺点
由上面的执行计划可见,它创建了一张中间表 ,走的是全表扫描,也就是说,中间表中的记录越多,该执行效率就越慢,观察以下语句,从500000开始查,查找 1500000 条数据;
select score, release_date, film_name,introduction from film a join (select id from film order by score limit 500000, 1500000) b on a.id = b.id;
消耗的时间为:911ms,接近一秒
所以我们可以通过业务的方法,限制每次查询的条数即可
索引的字段要根据排序的字段走,且要满足最左匹配原则
create table t_order ( id integer primary key auto_increment, col_1 int not null , col_2 int not null , col_3 int not null )
select * from t_order order by col_1, col_2, col_3
, 需要创建联合索引 col_1,col_2,col_3
select * from t_order order by col_1, col_2
,需要创建联合索引 col_1, col_2, col_3
select * from t_order order by col_1 asc, col_2 desc
,需要创建联合索引 col_1 asc, col_2 desc
,指定索引的排序规则,只有在 MySQL 8 中才支持
索引失效的情况(避免出现 using filesort)
没有遵守最左匹配原则select * from t_order order by col_1, col_3
select * from t_order order by col_2, col_3
可见都使用到了 ****using filesort
以第一条为例
最左匹配原则的实质是:先根据第一列排序,若第一列的值相同就根据第二列来排序,若第二列的值相同就根据第三列来排序,以此类推;
第一条 SQL 中,排序的字段为 col_2 和 col_3 明显 在抛开 col_1 的情况下,col_2 和 col_3 的顺序是无序的,故要使用 using filesort,不能依靠索引来进行排序;
使用了范围查询select * from t_order where col1 >= 1 and col1 <= 4 order by col_2
select * from t_order where col1 in(1,2,4) order by col_2
若走该复合索引(col_1, col_2, col_3)
,可以发现查询计划中使用到了using filesort
解释
经过 col_1 的筛选后,col_2 的数据都是无序的
所以要使用 using filesort 再次根据 col_2 排序
若使用等值查询,则不会出现 using filesort
,前提是要满足最左匹配原则
select col_1, col_2 from t_order where col_1 = 2 order by col_2;
若不满足 最左匹配原则
select col_1, col_3 from t_order where col_1 = 2 order by col_3;
则使用到了 using filesort
以上就是关于MySQL查询语句的优化详解的详细内容,更多关于MySQL查询语句优化的资料请关注脚本之家其它相关文章!
下一篇:最后一页
这篇文章主要介绍了MySQL查询语句的优化方法,分别介绍了子查询优化,分页查询优化以及排序查询优化,对学
格隆汇4月21日丨泡泡玛特(09992 HK)宣布,于2023年4月21日,公司根据首次公开发售后股份奖励计划的条款向8
▾4月15日,由中国美术学院、上海博物馆主办,中国美术学院艺术人文学院、艺术史学研究中心承办的“艺术...
(记者王坚)据中铁一局消息,由中铁一局一公司(广州分公司)负责主要施工、中铁一局新运公司共同参与建设的梅
4月21日,北京商报记者获悉,全球支付平台PingPong近日获得英国电子货币机构(EMI)牌照,获英国金融行为监
1、不管送什么礼物?,只要收礼物的人收到你送的礼物都是一种惊喜,她会特别的高兴。2、朋友之间在乎得不是
4月17日,为进一步全面提升抚州市校园食品安全治理水平、全力保障抚州市广大师生“舌尖上的安全”,抚州...
为壮大志愿服务队伍,颛桥镇新时代文明实践分中心不断探索、孵化、培育更多的志愿服务团队和优秀项目。今年
每经记者:袁园每经编辑:陈旭空缺两个月之后,中国人保终于迎来了新任党委书记人选。4月21日,中国人保发
1、3194错误,原因是服务器无法验证。2、部分可以通过修改HOSTS文件来解决。3、如果修改后重启问题依旧,那
本文转自:经济日报一季度住户存款增加9 9万亿元——超额储蓄转化为消费须多方发力中国人民银行近日公...
平安资管21日晚间再度发布声明称:“我们关注到汇丰就平安声明的回应。汇丰的声明,只是重复了过去对分...
为切实加强结算账户管理,提升精细化管理水平,农发行固阳县支开展了存量结算账户排查监督检查。高度重视,
在较强冷空气的影响下,昨天(20日)开始,多地气温开始“断崖式”下跌,以郑州为例,昨天10时到今天06...
(图片来源:视觉中国)去年6月以来,萦绕在键盘生产商传艺科技(002866 SZ)身上的最大议题莫过于跨界钠电
2023赛季中超第二轮,成都蓉城在凤凰山体育公园专业足球场迎战作客的沧州雄狮。
保利发展一季度实现归母净利润27 21亿元同比增长7 52%
自国家统计局4月18日发布今年一季度主要经济数据以来,各个省份近日陆续发布本地数据。
1、最近有不少朋友问小编说,自己的电脑按完开机键后,黑屏,没反应,无法开机!那么,电脑开机黑屏、没反应
长江日报大武汉客户端4月21日讯(记者周韧通讯员江芹)“高血压病人能不能吃小龙虾?”“为什么不胖的人...
X 关闭
X 关闭
04-22 05:49:00
04-22 05:32:04
04-22 05:16:03
04-22 05:00:21
04-22 04:31:03