2013-05-15 181 views
0

我有3个表:有没有一种方法来优化这个SQL Server查询?

表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 

我得到我所需要的数据,但此查询时间太长,反正是有优化它,而无需修改表指数?

事情指出:

  • 表2和表3是不一样的表。

  • 我需要从table2和table3中获取“last_updated”的整行,而不仅仅是日期。

编辑**

查询使用WHERE table1.id = id时,返回一个记录服用约3-4秒。

表1有〜84000区域经济共同体

表2有〜96000区域经济共同体

表3有〜81000区域经济共同体

+1

table2.date_updated和table3.date_updated *上的索引*可能*有帮助。但你最好的选择是总是看执行计划。 –

+0

但是,如果没有列出索引的内容,您提到的是不修改索引,我们不一定建议更多。我会通过(id,date_updated) – DRapp

+0

@DRapp在这两个表上有一个索引。'id'不是'date_updated'列只有索引 – SOfanatic

回答

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)和表3(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 

这消除了完全的分组,具有相关子查询替换它 - 和相关子查询应该变成一个小指标指数扫描。

+0

第一个不适合我,因为我正在寻找具有'max(date)'的整行;然而,您提供的第二个查询帮助我重新编写了查询,现在它返回的时间为0.2秒,而不是之前的3-4秒。通过使用第二个查询,不需要添加任何索引。 – SOfanatic

0

我知道你不修改索引所提到的,但你正在尝试做的就只能是如果您有每个“Table2”和“Table3”在

(fkId,date_updated)上具有索引,则会进一步优化。

如果您在每个表的“ID”列中只有一个索引,那么连接上显然没有任何优化。您至少需要使用Table1的外键。但是,由于这将是一个新的索引表,它不应该伤害任何东西,但只会帮助您的查询。在表2和表3上做这个索引。

+0

因此只有'fkId'的索引对于table2和table3不会有帮助这个查询,对吗? – SOfanatic

+0

这会有所帮助,但不会像(fkID,date_updated)那么多。大多数情况下,基于关键字AND其他一列(这将成为典型的查询条件基础)可以获得多字段索引。如果查询只需要FK,没问题,它仍然可以使用索引。如果它可以利用两个领域,甚至更好。只要查询FK,什么都不会丢失。 – DRapp