我有數據樣本的表格,有時間戳和一些數據。每個表在時間戳上都有一個聚集索引,然後是一個特定於數據的密鑰。數據樣本不一定是等距的。避免在SQL Server GROUP BY中進行不必要的排序?
我需要在特定的時間範圍內對數據進行縮減採樣以繪製圖表 - 例如,從100,000行到N,其中N大約是50.雖然我可能不得不妥協於算法的「正確性」從DSP的角度來看,我想保留在SQL中出於性能原因。
我目前的想法是將時間範圍內的樣本分組到N個框中,然後取每組的平均值。在SQL中實現此目的的一種方法是將分區函數應用於範圍從0到N-1(含)的日期,然後是GROUP BY和AVG。
我認爲這個GROUP BY可以在沒有排序的情況下執行,因爲日期來自聚簇索引,分區函數是單調的。但是,SQL Server似乎沒有注意到這一點,它發出的代碼佔執行代價的78%(在下面的例子中)。假設我是對的,這種類型是不必要的,我可以使查詢速度提高5倍。
有沒有辦法強制SQL Server跳過排序?還是有更好的方法來解決這個問題?
乾杯。 本
IF EXISTS(SELECT name FROM sysobjects WHERE name = N'test') DROP TABLE test
CREATE TABLE test
(
date DATETIME NOT NULL,
v FLOAT NOT NULL,
CONSTRAINT PK_test PRIMARY KEY CLUSTERED (date ASC, v ASC)
)
INSERT INTO test (date, v) VALUES ('2009-08-22 14:06:00.000', 1)
INSERT INTO test (date, v) VALUES ('2009-08-22 17:09:00.000', 8)
INSERT INTO test (date, v) VALUES ('2009-08-24 00:00:00.000', 2)
INSERT INTO test (date, v) VALUES ('2009-08-24 03:00:00.000', 9)
INSERT INTO test (date, v) VALUES ('2009-08-24 14:06:00.000', 7)
-- the lower bound is set to the table min for demo purposes; in reality
-- it could be any date
declare @min float
set @min = cast((select min(date) from test) as float)
-- similarly for max
declare @max float
set @max = cast((select max(date) from test) as float)
-- the number of results to return (assuming enough data is available)
declare @count int
set @count = 3
-- precompute scale factor
declare @scale float
set @scale = (@count - 1)/(@max - @min)
select @scale
-- this scales the dates from 0 to n-1
select (cast(date as float) - @min) * @scale, v from test
-- this rounds the scaled dates to the nearest partition,
-- groups by the partition, and then averages values in each partition
select round((cast(date as float) - @min) * @scale, 0), avg(v) from test
group by round((cast(date as float) - @min) * @scale, 0)
在這個例子中,應該是很容易分析至少(... - @ min)* @scale部分。不幸的是,將「日期」列存儲爲浮點數似乎沒有什麼區別。 但是,最終你說得對:期待SQL Server自動解決這個問題有點樂觀。我真正希望的是一種告訴它假設數據已經被排序的方法。 :) 關於FLOAT不精確,我認爲DATETIME只是一個FLOAT內部? – 2009-08-22 19:03:25
查看我的日期和浮動'內部'假設的更新。 – 2009-08-22 20:20:08
啊,這很有趣!謝謝。 – 2009-08-22 21:04:38