执行顺序
- 先子查询过滤再联合
SELECT XXX FROM(select * from edw_data_dyd.overrun_offsite_info WHERELENGTH( 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")) aLEFT 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
WHEREc.regionalcode IS NOT NULLAND c.regionalname IS NOT NULLand ooir.flag = 1
这种方式是,overrun_offsite_info 、overrun_offsite_info_response 先过滤数据,然后再进行联合查询(预处理)
- 先联合再过滤
SELECT XXX FROMedw_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
WHERELENGTH( 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 NULLAND c.regionalname IS NOT NULLand a.unique_id is not nulland ooir.flag = 1
这种方式:数据库表先进行联合查询,形成自然连接,再进行条件过滤
通过explain查询后,得到的执行顺序,过滤条数是一致的。
因此以上两种方式执行时间是一样的,这两种写法被mysql查询优化器优化后,应该是一样执行顺序。
执行时间
- 在overrun_offsite_info_response 没有添加过滤条件是,执行时间是1000多秒,因为overrun_offsite_info_response 的数据量是300多万条数据,因此自然连接后的数据量特别的大。
- 解决方法; 给 overrun_offsite_info_response 添加 CREATED_TIME字段,过滤数据后,sql的执行时间从1000多秒提升到5秒,极大地优化了查询。