我使用以下查询
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
会导致
将查询更改为
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
现在出现了
对于表a
,它仍在搜索90%的记录(总记录大约为68k)。
答案 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
上的连接和查询指定它们。