执行顺序
- 先子查询过滤再联合
SELECT XXX FROM
(select * from edw_data_dyd.overrun_offsite_info WHERE
LENGTH( VEHICLE_ID ) >= 12
AND CREATED_TIME >= DATE_ADD(NOW(),INTERVAL -1 HOUR)
AND CREATED_TIME < NOW()
AND VEHICLE_ID not like '%无车牌%'
AND VEHICLE_ID not like '%无法识别%'
AND a.VEHICLE_TYPE_ID = '1'
AND VEHICLE_TYPE_ID in('1',"11","12","13","14","15","16")
) a
LEFT JOIN edw_data_eda.global_vehicle b ON RIGHT ( a.VEHICLE_ID, 7 ) = b.plate_number and LEFT(a.VEHICLE_ID,1) = LEFT(b.PLATE_COLOR_NAME,1)
LEFT JOIN edw_data_dyd.sys_station c ON a.STATION_IP = c.stationcode
inner join ( select * from overrun_offsite_info_response where CREATED_TIME >= DATE_ADD(NOW(),INTERVAL -1 HOUR) AND CREATED_TIME < NOW() ) as ooir on a.unique_id = ooir.unique_id
WHERE
c.regionalcode IS NOT NULL
AND c.regionalname IS NOT NULL
and ooir.flag = 1
这种方式是,overrun_offsite_info 、overrun_offsite_info_response 先过滤数据,然后再进行联合查询(预处理)
- 先联合再过滤
SELECT XXX FROM
edw_data_dyd.overrun_offsite_info a
LEFT JOIN edw_data_eda.global_vehicle b ON RIGHT ( a.VEHICLE_ID, 7 ) = b.plate_number and LEFT(a.VEHICLE_ID,1) = LEFT(b.PLATE_COLOR_NAME,1)
LEFT JOIN edw_data_dyd.sys_station c ON a.STATION_IP = c.stationcode
inner join overrun_offsite_info_response as ooir on a.unique_id = ooir.unique_id
WHERE
LENGTH( a.VEHICLE_ID ) >= 12
AND a.CREATED_TIME >= DATE_ADD(NOW(),INTERVAL -1 HOUR)
AND a.CREATED_TIME < NOW()
AND ooir.CREATED_TIME >= DATE_ADD(NOW(),INTERVAL -1 HOUR)
AND ooir.CREATED_TIME < NOW()
AND a.VEHICLE_ID not like '%无车牌%'
AND a.VEHICLE_ID not like '%无法识别%'
AND a.VEHICLE_TYPE_ID in('1',"11","12","13","14","15","16")
AND c.regionalcode IS NOT NULL
AND c.regionalname IS NOT NULL
and a.unique_id is not null
and ooir.flag = 1
这种方式:数据库表先进行联合查询,形成自然连接,再进行条件过滤
通过explain查询后,得到的执行顺序,过滤条数是一致的。
因此以上两种方式执行时间是一样的,这两种写法被mysql查询优化器优化后,应该是一样执行顺序。
执行时间
- 在overrun_offsite_info_response 没有添加过滤条件是,执行时间是1000多秒,因为overrun_offsite_info_response 的数据量是300多万条数据,因此自然连接后的数据量特别的大。
- 解决方法; 给 overrun_offsite_info_response 添加 CREATED_TIME字段,过滤数据后,sql的执行时间从1000多秒提升到5秒,极大地优化了查询。