很难想想会在600条数据和4万条数据的两张表联表查询的的情况下,查询花了10多s。这里记录一下排查过程吧,最后的错误原因也抽象的。
显示两个表的交集,如果不在两张表中就不进行显示
以表1为驱动表,表2为被驱动表的数据,查出来的结果显示左边的所有数据,然后右边显示的是和左边有交集部分的数据。
以表2为驱动表,表1为被驱动表的数据,查出来的结果显示右边的所有数据,然后左边显示的是和右边有交集部分的数据。
JDK8、Maven3.X、SSM项目、Oracle
每两个小时拉取最新的结果数据,在这种情况下,生成一个统计报表。其中当前4万多条的被驱动表称为A,600+数据的驱动表称为B。
SELECT
t1.CAR_IMG,
t1.VEH_LIC_PLT_NO,
t1.ALARM_TM,
t1.WARN_TP,
t2.DIST_NM,
t2.ENT_NM,
t1.ENT_MGMT_MBR,
t1.CON_PHONE,
t2.IND_NM
FROM
T_VEHICLE_POLLUT_QA_INFO t1,
T_VEHICLE_POLLUT_ENT_BASE_INFO t2
WHERE
t2.ENT_CODE = t2.ENT_CODE
AND t1.ALARM_TM BETWEEN TO_DATE ('2023-03-02 11:55:15', 'yyyy-mm-dd hh24:mi:ss')
AND TO_DATE ('2023-03-07 11:55:15', 'yyyy-mm-dd hh24:mi:ss');
没错跑了20S都没跑出来,直接依托答辩。
left join 把数据量小的表作为驱动表,数据量大的作为被驱动表,同时提前将表按条件过滤,代码如下:
对所有的查询字段设置索引,同时对联表的外键也建立索引。
既然查数据库很慢,那么就Juc 进行异步IO查数据库,当然这里异步查最后的响应时间也是取决于最耗费时间的任务。
CompletableFuture> guardFuture = CompletableFuture.supplyAsync(() -> guardDao.selectByMap(params), ThreadPoolUtil.getExecutorService());CompletableFuture> alarmFuture = CompletableFuture.supplyAsync(() -> alarmInfoDao.selectByMap(params), ThreadPoolUtil.getExecutorService());
自信满满,接口一测试,直接蒙蔽,这是人能看的?不过幸好从直接死机到现在能出来数据了,不过10S真的很难让人接受了
莫非是程序问题?我查看IDEA对SQL的打印,竟然耗费了10s多,以为后端的代码应该没有问题。
我直接将解析的SQL复制到Navicat中一测竟然只有0.2ms,数据量也不大,这到底怎么回事?
检查了数据库的连接,一看用的是VPN连接的远程的数据库……调回本地数据库,再次测试。
刚接手很多任务的时候,我知道你很急,但是你先别急。