mysql两表关联 将join替换为union效率问题

现在我在mysql中有两张表
表1.
在这里插入图片描述
表2.
在这里插入图片描述
假设这两张表来自一家麻辣烫的店铺,
表1表示某天(part_init_date)编号(number)的客户消费(cost)
表2表示某天(part_init_date)编号(number)的客户姓名(name)
两张表各30000条数据。如果在未设置关联字段为主键索引的情况下,用join的方法进行联表查询查询当天来吃麻辣烫的用户真名和花费。

select b.name,a.number,a.cost,a.part_init_date
from
(select number,cost,part_init_date from demo1) a
left join
(select number,name,part_init_date from demo2) b
on a.number = b.number and a.part_init_date = b.part_init_date
order by name,part_init_date
;

结果如下
在这里插入图片描述
用时84.988s

采用union的写法

select name,number,cost,part_init_date from(
select group_concat(name,'') as name,number,sum(cost) as cost,part_init_date from
(
select 'a' as name,number,cost,part_init_date
from demo1
union all
select name,number,0 as cost,part_init_date
from demo2
) a
group by number,part_init_date
)b;

结果如下
在这里插入图片描述
耗时0.539s

对比上面两个结果,我们好像可以得出结论利用union+group by+聚合函数的方法对俩个表联立查询会比较快一点。。。。但是且慢,我上面的实验是在未设置主键索引的情况下进行的,我们知道,如果为关联字段设置了主键索引(非主键也可以),join的效率会大大提高。。

alter table demo1 add constraint date1 primary key(part_init_date);
alter table demo2 add constraint date2 primary key(part_init_date);
-- 将part_init_date设置为主键索引    
select b.name,a.number,a.cost,a.part_init_date
from
(select number,cost,part_init_date from demo1) a
left join
(select number,name,part_init_date from demo2) b
on a.number = b.number and a.part_init_date = b.part_init_date
order by name,part_init_date
;

上述查询第一次需要 3.777s

以后查询时间稳定在0.16s左右(这是因为有缓存么?对于未添加主键索引的join检索,不论多少次查询速度都是一样的,所以这个缓存机制是不是在Index Nested-Loop Join算法里的?)

所以如果数据表中有索引项,那么用join效率是比union高的,反之用union效率高一点。

ps:关联字段不一定要主键索引,只要是索引就行,设置成唯一约束也可以,这样就相当于一个二级索引,由于二级索引需要检索主键索引,所以会慢一点,我实验过两个4列30000行的表关联排序用主键和二级索引差前后分别为0.18s,0.16s。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值