griffin702 发表于 2015-11-2 13:40:20

一个关于查询语句优化类的问题

本帖最后由 griffin702 于 2015-11-2 13:59 编辑

小弟新手,最近学习优化查询语句时发现一个弱弱的问题,不知哪位大神能否帮忙给一下比较精准的解释,万分感谢.先看一段我最开始些的一段查询语句:
首先需要计算出在第二天留存下来仍在活动的玩家数量(其中id1,time为log库下resource表中的字段,id2,CreateTime为role库下player表中的字段)
select count(distinct id1) from log.resource
where time BETWEEN date_add('2015-09-22 00:00:00', interval '1' day) and date_add('2015-09-22 23:59:59', interval '1' day)
and id1 in (select id2 from role.player
where CreateTime between '2015-09-22 00:00:00' and '2015-09-22 23:59:59')
然后小弟看了不少优化的建议,得到一个初步的优化方案:先将子查询改为连接查询.
而偏偏第一次动手优化时出现了极大的反差,也许不是方案错,可能是小弟自己写错或者其他等原因,不过还是希望大神帮忙解惑一下,下面看我修改后的语句(当然修改过后,得到的答案是没错的):
select count(distinct b.id1) from
(
select player.id2,player.CreateTime
from role.player
where player.CreateTime between '2015-09-22 00:00:00' and '2015-09-22 23:59:59'
) a
inner join
(
select resource.id1,resource.time
from log.resource
where resource.time between date_add('2015-09-22 00:00:00', interval '1' day) and date_add('2015-09-22 23:59:59', interval '1' day)
) b
on b.id1 = a.id2


由于小弟之前些的是存储过程,而这一个查询仅仅是存储过程中的一段小查询,拿来做实验而已,所以以上用的时间是一个函数的方式,而效果是一样的.

本文中的疑惑重点不在于此,而是2个语句本身应该是修改后的执行时间应比之前的要快,可最后却实际上变慢了,关键是还慢了不少.

之前执行时间 1.5 ,修改后执行时间 2.12

当然,2个表里都做全了必须的索引.

用explain查询也看过了,疑惑的是连接查询多出了2行未使用索引.

哪位大神帮忙看看,感谢!


nycle 发表于 2015-11-6 16:28:04

1.第2句明显比第1句有冗余字段了。
2.现在子查询已经进行过优化,除非驱动表不合理。

griffin702 发表于 2015-11-11 14:07:15

nycle 发表于 2015-11-6 16:28
1.第2句明显比第1句有冗余字段了。
2.现在子查询已经进行过优化,除非驱动表不合理。

谢谢,明白了.请问现在子查询进行过优化的程度可以达到效率优于联结表查询吗?

griffin702 发表于 2015-11-11 15:05:13

nycle 发表于 2015-11-6 16:28
1.第2句明显比第1句有冗余字段了。
2.现在子查询已经进行过优化,除非驱动表不合理。

select count(distinct id1) from log.resource
         where time BETWEEN date_add('2015-09-22 00:00:00', interval '1' day) and date_add('2015-09-22 23:59:59', interval '1' day)
         and id1 in ( select id2 from role.player
                               where CreateTime between '2015-09-22 00:00:00' and '2015-09-22 23:59:59' )
#执行时间1.17

select count(distinct b.id1) from
(select player.id2 from role.player where player.CreateTime between '2015-09-22 00:00:00' and '2015-09-22 23:59:59') a left join
(select resource.id1 from log.resource where resource.time between date_add('2015-09-22 00:00:00', interval '1' day) and date_add('2015-09-22 23:59:59', interval '1' day)) b
on a.id2 = b.id1
#执行时间1.24

select count(distinct resource.id1) from role.player left join log.resource
on player.id2 = resource.id1
where resource.time BETWEEN date_add('2015-09-22 00:00:00', interval '1' day) and date_add('2015-09-22 23:59:59', interval '1' day)
and player.CreateTime between '2015-09-22 00:00:00' and '2015-09-22 23:59:59'
#执行时间1.593条语句,查询目的相同,执行时间如上,其中第2条语句按你的指正,去除了冗余字段,但最终得到的结果仍没有第1条子查询来的快.
是否证明了你说的第2点,现在子查询进行了优化,优化后的效率已经超过了联结表查询呢?
页: [1]
查看完整版本: 一个关于查询语句优化类的问题