前两天同事提了一个问题,相同的SQL,两个人在各自的机器上执行的时间不同。再沟通了下,一个人使用的Navicat,秒级返回,另一个人使用的DBeaver,毫秒返回,但是执行的SQL是相同的。
SQL示例如下,
select * from tag
where publish_time>='2020-07-09 00:00:00'
and publish_time<='2020-08-08 23:59:59'
执行计划都是用到了publist_time字段的索引,
但是检索了下这个条件范围内结果集的总数,大概是50万,因为执行计划是按照非聚簇索引扫描,select所有的字段,所以还得回表,50万的数据,资源消耗,应该不小,执行慢是正常的。
测试了下,Navicat执行SQL,甚至出现了OOM的错,
但是在DBeaver,毫秒返回,
这是为什么?
我们看到,DBeaver返回信息中,标记了200行,再结合通过Navicat执行出现了OOM,是否因为在DBeaver中存在预提取?我们看下DBeaver的配置,确实有个结果集数据的获取值,默认是200,这和回显能对应,
为了证明这点,我们在DBeaver执行SQL的时候指定limit,他的执行时间,就很久了,和在Navicat很相近,
select * from tag
where publish_time>='2020-07-09 00:00:00'
and publish_time<='2020-08-08 23:59:59' limit 100000;
说明不同的客户端在得到结果集的机制上还是存在不同的,Navicat执行SQL就是所有的结果集数据(或许应该存在相同的配置),DBeaver则会控制结果集,默认配置很小,前者保证的是一次性得到所有数据,但是可能OOM,后者要得到所有的数据可能需要点多次,但是会节省内存,保证能得到数据,因此,针对不同的场景,各取所需即可。