我有3张桌子:
表1 :
id | name
1 | joe
2 | peter
3 | sandra
表2 :
id | fkId | date_updated
1 | 1 | 2013-01-31
2 | 1 | 2013-04-01
3 | 2 | 2013-02-04
4 | 2 | 2013-01-02
表3 :
id | fkId | date_updated
1 | 1 | 2013-01-31
2 | 3 | 2013-04-01
3 | 3 | 2013-02-04
4 | 2 | 2013-01-02
我有以下内容:
SELECT *
FROM
table1
LEFT OUTER JOIN
table2 ON table1.id = table2.fkId
LEFT OUTER JOIN
table3 ON table1.id = table3.fkId
GROUP BY
table1.id
HAVING
table2.date_updated = max(table2.date_updated)
AND table3.date_updated = max(table3.date_updated)
我的输出如下:
name | table2 | table3
joe | 2013-04-01 | 2013-01-31
peter | 2013-02-04 | 2013-01-02
sandra| | 2013-04-01
我得到了我需要的数据,但这个查询花了太长时间,无论如何要优化它而不修改表索引?
要指出的事情:
table2和table3不是同一个表。
我需要得到#34; last_updated"来自table2和table3,而不仅仅是日期。
编辑**
使用WHERE table1.id = id
时,查询大约需要3-4秒,以返回单个记录。
表1有~84000个记录
表2有~96000个记录
表3有~81000个记录
答案 0 :(得分:1)
根据您显示的数据,查询似乎是:
SELECT table1.name, MAX(table2.date_updated), MAX(table3.date_updated)
FROM table1 LEFT OUTER JOIN
table2
ON table1.id = table2.fkId LEFT OUTER JOIN
table3 ON table1.id = table3.fkId
GROUP BY table1.id
table2(fkid, date_updated)
和table3(fkid,date_updated)的索引可能会有所帮助。
实际上,对于这样的索引,这个版本可能会有更好的性能:
select table1.name,
(select date_updated from table2 where table1.id = table2.fkid order by date_updated desc limit 1
) as T2,
(select date_updated from table3 where table1.id = table3.fkid order by date_updated desc limit 1
) as T3
from table1
这完全消除了分组,用相关的子查询替换它 - 相关的子查询应该变成索引小索引扫描。
答案 1 :(得分:0)
我知道你在没有修改索引的情况下提到了,但是如果每个“Table2”和“Table3”都有索引,那么你想要做的只会更加优化
(fkId,date_updated)。
如果每个表的“ID”列上只有一个索引,那么显然没有任何内容可以在连接上进行优化。您至少需要在Table1的外键上使用它。但由于这将是桌面上的一个新索引,它不应该伤害任何东西,而只是帮助你的查询。在BOTH Table2和Table3上做这个索引。