前两天同事提了一个问题,相同的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字段的索引,

MySQL客户端预读数据的区别_sql

但是检索了下这个条件范围内结果集的总数,大概是50万,因为执行计划是按照非聚簇索引扫描,select所有的字段,所以还得回表,50万的数据,资源消耗,应该不小,执行慢是正常的。

测试了下,Navicat执行SQL,甚至出现了OOM的错,

MySQL客户端预读数据的区别_mongodb_02

但是在DBeaver,毫秒返回,

MySQL客户端预读数据的区别_索引_03

这是为什么?

我们看到,DBeaver返回信息中,标记了200行,再结合通过Navicat执行出现了OOM,是否因为在DBeaver中存在预提取?我们看下DBeaver的配置,确实有个结果集数据的获取值,默认是200,这和回显能对应,

MySQL客户端预读数据的区别_mongodb_04

为了证明这点,我们在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,后者要得到所有的数据可能需要点多次,但是会节省内存,保证能得到数据,因此,针对不同的场景,各取所需即可。