MySql LEFT JOIN需要很长时间 - 已添加索引

时间:2013-06-11 08:16:46

标签: mysql left-join

我使用以下查询

SELECT a.job_number as f31jn, b.job_number as f32jn
FROM 
f31 a LEFT JOIN f32 b 
ON (a.job_number = b.job_number AND a.date_audit = b.date_audit)
WHERE date_format(a.date_audit, '%b %Y') = 'Dec 2012'
GROUP BY a.job_number, a.ref_id, b.job_number, b.ref_id

上述查询需要 160 秒才能完成。

我已将索引添加到以下列:

f31 - job_number, date_audit (separate indexes)
f32 - job_number, date_audit (separate indexes)
上述查询的

EXPLAIN会导致 EXPLAIN

修改

将查询更改为

SELECT a.job_number as f31jn, b.job_number as f32jn
FROM 
f31 a LEFT JOIN f32 b 
ON (a.job_number = b.job_number AND a.date_audit = b.date_audit)
WHERE a.date_audit >= '2012-12-01' AND a.date_audit < '2013-01-01'
GROUP BY a.job_number, a.ref_id, b.job_number, b.ref_id

仍然执行时间不会降低。它保持在150到160秒的相同范围内。

EXPLAIN现在出现了 EXPLAIN 2

对于表a,它仍在搜索90%的记录(总记录大约为68k)。

2 个答案:

答案 0 :(得分:3)

MySQL无法使用索引来帮助date_format(a.date_audit, '%b %Y') = 'Dec 2012'

您是否在job_number和date_audit或一个组合索引上有单独的索引。如果它是一个组合索引,那么MySQL再也不能在date_audit上使用它进行任何形式的查询。在date_audit上自己创建一个索引,或者在date_audit first和job_number second之间创建一个组合索引。

然后转换WHERE子句以将date_audit与实际日期值进行比较。

在黑暗中这是一个镜头,但值得一试:

首先,时间:

SELECT * from f31 a 
WHERE a.date_audit >= '2012-12-01' 
  AND a.date_audit < '2013-01-01'

应该很快。如果没有,则需要验证索引以及date_audit列的类型(DATE,DATETIME或TIMESTAMP)。

然后:

SELECT DISTINCT a.job_number as f31jn, b.job_number as f32jn
FROM 
  (SELECT * from f31 aa 
   WHERE aa.date_audit >= '2012-12-01' 
     AND aa.date_audit < '2013-01-01') as a    
LEFT JOIN f32 b 
ON (a.job_number = b.job_number AND a.date_audit = b.date_audit)

如果这不符合要求,那么请设置一个SQL Fiddle,其中包含架构和至少几个测试数据。

答案 1 :(得分:1)

首先考虑重构这一部分:

date_format(a.date_audit, '%b %Y') = 'Dec 2012'

分为:

a.date_audit >= '2012-12-01' && a.date_audit < '2013-01-01'

另外,尝试添加组合索引,如下所示:

f31 - (date_audit, job_number)
f32 - (date_audit, job_number)

MySQL每个表只使用一个索引,因此将它们组合在一起应该为date_audit上的连接和查询指定它们。