2016-03-06 160 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 
       ); 

這要約阿希姆提出相同的索引。在某些情況下,這可能會稍微快一點。你可以在你的數據上測試兩者。