2016-03-06 78 views
-1

比方说,我有一个表,这个类型的数据:是否有可能避免这种查询的子查询?

Parent Value   DateFor  ValueType 
3177 50.110000  2016-03-05 1 
3177 254390.000000 2016-03-05 2 
3177 50.110000  2016-03-06 1 
3177 254390.000000 2016-03-06 2 
3294 40.800000  2016-03-05 1 
3294 20280.000000 2016-03-05 2 

我的表有ID的主索引(ID这里没有显示)和父表的外关系,与Parent的帮助柱。

,我想选择由值类型的最新值,每个家长:

3177 50.110000  2016-03-06 1 
3177 254390.000000 2016-03-06 2 
3294 40.800000  2016-03-05 1 
3294 20280.000000 2016-03-05 2 

解说:我忽略2015年3月5日这两个值父3177,因为它具有数据2016- 03-06。但我从父母3294的2016-03-05获取数据,因为这是我拥有的最新数据。

什么是最高性能的查询,将实现这一目标?因为我的表有几百万行...

是否有可能避免子查询?

+3

'如何优化此查询的性能?'查询在哪里? – lad2025

+0

哪个数据库引擎? – trincot

+0

@ lad2025我有一个基本的'选择'与where过滤器,我提供一个父母,没有分组,但我不知道如何建立一个没有过滤器和分组的查询,取得所有数据的前1名... – ibiza

回答

3

使用分析函数以及覆盖索引应该可以获得很好的性能,从而牺牲一些磁盘空间;

CREATE INDEX ix_test 
     ON myTable([Parent], [ValueType], [DateFor] DESC) INCLUDE ([Value]); 

GO 

SELECT [Parent], [Value], [DateFor], [ValueType] 
FROM (
    SELECT *, ROW_NUMBER() 
      OVER (PARTITION BY [Parent], [ValueType] ORDER BY [DateFor] DESC) rn 
    FROM myTable 
) z 
WHERE rn=1; 
+0

谢谢,这看起来不错!问题:为什么'INCLUDE([Value])'而不是将'[Value]'放在索引本身中(其他列在'ON'子句中)? – ibiza

+1

@ibiza在这里你可以使用'INCLUDE',但通常会节省一些空间。有关更多详细信息,请参阅[此处](https://msdn.microsoft.com/en-us/library/ms190806(v = sql.120).aspx)。 –

1

这个问题过于宽泛,因此答案有点泛泛。使用具有子查询的SQL查询或Temp Table(后者可能会导致更好的性能)。首先,通过SELECT MAX(DateFor) as MinDate FROM [YourTable] Group BY [Parent], [ValueType]得到最早的日期(最小值),然后在WHERE条款中使用MinDate运行第二个SELECT声明。希望这会有所帮助。

1

也可能有不错的表现另一种方法是:

SELECT [Parent], [Value], [DateFor], [ValueType] 
FROM t 
WHERE DateFor = (SELECT MAX(t2.DateFor) 
       FROM t t2 
       WHERE t2.Parent = t.Parent AND t2.ValueType = t.ValueType 
       ); 

这要约阿希姆提出相同的索引。在某些情况下,这可能会稍微快一点。你可以在你的数据上测试两者。