我需要從已知集合中選擇每個類別的頂行(與this question有點類似)。問題是,如何使這個查詢在大量的行上有效。爲集合中的每個類別有效選擇頂行
例如,我們創建一個表格,在幾個地方存儲溫度記錄。
CREATE TABLE #t (
placeId int,
ts datetime,
temp int,
PRIMARY KEY (ts, placeId)
)
-- insert some sample data
SET NOCOUNT ON
DECLARE @n int, @ts datetime
SELECT @n = 1000, @ts = '2000-01-01'
WHILE (@n>0) BEGIN
INSERT INTO #t VALUES (@n % 10, @ts, @n % 37)
IF (@n % 10 = 0) SET @ts = DATEADD(hour, 1, @ts)
SET @n = @n - 1
END
現在我需要獲得最新的記錄每個地區1,2,3
這種方式是有效的,但不能很好地(而且看上去髒)。
SELECT * FROM (
SELECT TOP 1 placeId, temp
FROM #t
WHERE placeId = 1
ORDER BY ts DESC
) t1
UNION ALL
SELECT * FROM (
SELECT TOP 1 placeId, temp
FROM #t
WHERE placeId = 2
ORDER BY ts DESC
) t2
UNION ALL
SELECT * FROM (
SELECT TOP 1 placeId, temp
FROM #t
WHERE placeId = 3
ORDER BY ts DESC
) t3
以下看起來更好但效率低得多(根據優化器,30%vs 70%)。
SELECT placeId, ts, temp FROM (
SELECT placeId, ts, temp, ROW_NUMBER() OVER (PARTITION BY placeId ORDER BY ts DESC) rownum
FROM #t
WHERE placeId IN (1, 2, 3)
) t
WHERE rownum = 1
的問題是,在#T執行聚集索引掃描和300個檢索行,分類,編號,然後過濾,只留下3行後者查詢執行計劃中。對於前一個查詢,三次獲取一行。
有沒有辦法有效地執行查詢沒有大量的聯合?
包含示例代碼+1的問題 – 2010-06-04 15:17:59