学习SQL子查询优化

前言

今天做项目时,遇到需要用到子查询的地方。但是使用子查询后查询效率很低,在网上找资料后,了解到 子查询的执行效率居然受制于外层查询的记录数
技术大牛的博客原文:点击查看大牛的SQL优化。

未优化之前的代码

select 
	c.customer_id, 
	a.union_id, 
	a.ip, 
	a.query_string, 
	b.name, 
	a.query_date, 
	a.has_result 
from 
	customer_query a 
left join 
	mat b on a.store_id = b.ip_id
inner join 
	customer c on a.customer_id = c.customer_id
where 
	a.`type` = 1 and a.query_date > '2019-05-01'
	and exists (select 1 from order q where q.customer_id = c.customer_id);

其中我使用的是exists,这个比 in 效率高一点。但是存在子查询后,效率仍然很低。
未优化之前查询需要4秒钟时间。
在这里插入图片描述
解析查询语句:
由于子查询对 order 的查询方式依赖于外层 的查询,也就是可以分为两步:

select 
	c.customer_id, 
	a.union_id, 
	a.ip, 
	a.query_string, 
	b.name, 
	a.query_date, 
	a.has_result 
from 
	customer_query a 
left join 
	mat b on a.store_id = b.ip_id
inner join 
	customer c on a.customer_id = c.customer_id
where 
	a.`type` = 1 and a.query_date > '2019-05-01'

在这里插入图片描述

  • 第一步,通过这个查询获得一个rows = 41290的结果集,
  • 第二步,结果集里面的每一条数据再与子查询组成一个新的查询语句,也就是说,子查询要执行四万多次,所以这样效率就慢了。

优化策略

与临时表联合查询。

select 
	table1.customer_id, 
	table1.union_id, 
	table1.ip, 
	table1.query_string, 
	table1.name, 
	table1.query_date, 
	table1.has_result 
from
	(select 
		c.customer_id, 
		a.union_id, 
		a.ip, 
		a.query_string, 
		b.name, 
		a.query_date, 
		a.has_result 
	from 
		customer_query a 
	left join 
		mat b on a.store_id = b.ip_id
	inner join 
		customer c on a.customer_id = c.customer_id
	where 
		a.`type` = 1 and a.query_date > '2019-05-01') table1,
	(select customer_id from order) table2
where table1.customer_id = table2.customer_id

把外查询作为一个表,再将子查询作为一个临时表,两个表联合查询。

此次查询结果如下:只花了0.079秒,成果优化。
在这里插入图片描述

结语

技术很多很杂,学会后很久不用还是会忘记,故作此记录,仅供自己回顾用,如果有错还望指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值