LEFT JOIN在mySQL中花费了很长时间

时间:2015-10-01 02:58:09

标签: php mysql sql

我有一个带有LEFT JOIN的mySQL查询,运行时间超过30秒,我需要大幅加快速度。查询如下:

SELECT asset.asset_id, schedule.schedule_name, asset.asset_type, asset_sign.sign_type, 
       asset.creation_date, asset.update_date, asset.sms, asset.gps, survey.location, 
       survey.address, asset.condition_grade, 
       asset.performance_grade, asset.aesthetics_grade  
FROM survey, SCHEDULE, asset 
  LEFT JOIN asset_sign 
   ON asset_sign.asset_id = asset.asset_id 
WHERE asset.sms = survey.sms 
      AND asset.deletion_date='0000-00-00' 
      AND asset.schedule_id = schedule.schedule_id 
      AND schedule.schedule_id = '1'

资产和资产表非常庞大,约有10,000行。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

  1. 确保asset_sign.asset_id已编入索引
  2. 确保asset.asset_id已编入索引
  3. 为了清晰起见,重写您的查询:

    SELECT <whatever> 
    FROM survey  
        JOIN asset ON asset.sms = survey.sms  
        JOIN schedule ON asset.schedule_id = schedule.schedule_id  
        LEFT JOIN asset_sign ON asset_sign.asset_id = asset.asset_id  
    WHERE asset.deletion_date='0000-00-00'  
        AND schedule.schedule_id = '1'
    
  4. 确保asset.sms已编入索引

  5. 确保survey.sms已编入索引
  6. 确保asset.schedule_id已编入索引
  7. 确保将schedule.schedule_id编入索引
  8. 这至少是因为您应该加入已编制索引的内容。你也可以:

    1. 索引您在WHERE子句中使用的列
    2. 将WHERE子句中的条件移动到各自的JOIN条件中,以便在JOIN步骤中进行过滤,而不是在所有内容都已加入之后。

      SELECT <whatever> 
      FROM survey  
          JOIN asset ON asset.sms = survey.sms AND asset.deletion_date='0000-00-00'
          JOIN schedule ON asset.schedule_id = schedule.schedule_id AND schedule.schedule_id = '1'
          LEFT JOIN asset_sign ON asset_sign.asset_id = asset.asset_id
      

答案 1 :(得分:2)

您应该考虑修改您的查询以获得如下所示的正确联接。此外,将条件从WHERE移动到JOIN ON子句以具有正确的外连接效果。

SELECT asset.asset_id, 
       schedule.schedule_name, 
       asset.asset_type, 
       asset_sign.sign_type, 
       asset.creation_date, 
       asset.update_date, 
       asset.sms, 
       asset.gps, 
       survey.location, 
       survey.address, asset.condition_grade, 
       asset.performance_grade, asset.aesthetics_grade  
FROM survey 
LEFT JOIN assest ON asset.sms = survey.sms 
AND asset.deletion_date='0000-00-00'
LEFT JOIN asset_sign ON asset_sign.asset_id = asset.asset_id 
LEFT JOIN SCHEDULE ON asset.schedule_id = schedule.schedule_id  
AND schedule.schedule_id = '1';