我有一張表,其中包含大量的數據,我們特別關注date
字段。原因是數據量增加了30倍,舊的方式很快就會崩潰。查詢我希望你可以幫我優化需求:試圖優化一個查詢,選擇「近似最接近的記錄」
- 採取日期的列表(由CTE基於表值函數生成)
- 檢索單個記錄爲每個日期的
- 基於的「最接近的」一些定義
例如,當前表包含以5秒的數據(+/-一點)的間隔。我需要對該表格進行採樣並獲得最接近30秒間隔的記錄。
我現在擁有的作品很好。我只是很好奇,如果有更好的方法來優化它。如果我可以在Linq To SQL中使用它,那也會很整潔。鑑於日期值的數量(大約200萬行),我甚至對索引建議感興趣。
declare @st datetime ; set @st = '2012-01-31 05:05:00';
declare @end datetime ; set @end = '2012-01-31 05:10:00';
select distinct
log.* -- id,
from
dbo.fn_GenerateDateSteps(@st, @end, 30) as d
inner join lotsOfLogData log on l.Id = (
select top 1 e.[Id]
from
lotsOfLogData as log -- contains data in 5 second intervals
where
log.stationId = 1000
-- search for dates in a certain range
AND utcTime between DateAdd(s, -10, dt) AND DateAdd(s, 5, dt)
order by
-- get the 'closest'. this can change a little, but will always
-- be based on a difference between the date
abs(datediff(s, dt, UtcTime))
)
-- updated the query to be correct. stadionId should be inside the subquery
lotsOfLogData的表結構如下。站點ID(可能是50)相對較少,但每個站點都有很多記錄。當我們查詢時,我們知道電臺ID。
create table ##lotsOfLogData (
Id bigint identity(1,1) not null
, StationId int not null
, UtcTime datetime not null
-- 20 other fields, used for other calculations
)
fn_GenerateDateSteps返回這樣的數據集,爲參數給出:
[DT]
2012-01-31 05:05:00.000
2012-01-31 05:05:30.000
2012-01-31 05:06:00.000
2012-01-31 05:06:30.000 (and so on, every 30 seconds)
我有一個臨時表做到了這一點爲好,以這種方式,但說出來一點點有點貴。
declare @dates table (dt datetime, ClosestId bigint);
insert into @dates (dt) select dt from dbo.fn_GenerateDateSteps(@st, @end, 30)
update @dates set closestId = (-- same subquery as above)
select * from lotsOfLogData inner join @dates on Id = ClosestId
編輯:搞掂
了200K +行與現在的工作。我嘗試了兩種方式,並且使用適當的索引(id/time + includes(..所有列...)工作得很好。然而,我最終使用了一個簡單的(和現有的) 。在[ID +時間]指標的更廣泛的理解查詢是爲什麼我在一個結算也許還有更好的方式來做到這一點,但我不能看到它:d
-- subtree cost (crossapply) : .0808
-- subtree cost (id based) : .0797
-- see above query for what i ended up with
交叉應用要求我在stationid/time上做一個索引包括*表中的所有*其他數據。沒有索引,它的運行與裸體查詢完全一樣,所以在這種情況下,交叉是不會工作的:)雖然我甚至不知道它,所以謝謝! – 2012-02-20 03:50:16
哦,而且我確實在該查詢中有一個錯誤;)我需要*將stationId放入子查詢中,否則我會匹配範圍內的任何stationId。這樣做後,正確的指數被使用,一切都超快(ish) – 2012-02-20 03:51:31
@AndrewBacker - 走開,但謝謝你讓我們知情。 – 2012-02-24 00:16:54