2014-10-02 48 views
1

我有一個非常依賴日期的應用程序。它每天存儲數千條記錄,幾乎每個查詢都需要檢查日期字段以確保它匹配搜索日期。但隨着應用程序的增長,性能正在下降。更改應用程序以提高性能是必需的,但需要很長時間。因此,在我開始之前,我希望瞭解如何改變它以獲得最佳結果。在很多記錄上的日期時間搜索性能

當前日期存儲在datetime列(帶索引)中。在某些情況下,需要時間(EG:您將在2014-10-02 10:24接到信件),有些情況下不是(EG:我需要從2014-10-01到2014-10的每日運輸-30)。我想要做的第一件事是分割日期和時間字段,所以當搜索日期時,我不必擔心時間。

獲取他們使用的特定日期的記錄DATEDIFF(D, DateTime, GetDate())=0,但不使用索引(完整掃描)。爲了解決我可以使用Datum=DATEADD(dd, 0, DATEDIFF(dd, 0, GetDate()))它使用索引,因此更快。

但我想知道,將日期分爲三個單獨的列(年,月,日)還是完全跳過日期函數會更快?還是有另一種方法來顯着加快速度?

例/原因分裂:

Table members: Id, MemberId, Datetime, CarId 
Table car: Id, Name 

我今天需要推動所有的汽車名單。所以:

SELECT Id, Name 
FROM Car 
WHERE Id IN (
    SELECT CarId 
    FROM Members 
    WHERE DATEDIFF(D, DateTime, GetDate())=0 
) 

現在,如果日期時間將被分隔,我可以使用(使用索引)

SELECT Id, Name 
FROM Car 
WHERE Id IN (
    SELECT CarId 
    FROM Members 
    WHERE Date=DATEADD(dd, 0, DATEDIFF(dd, 0, GetDate())) 
) 

現在我想顯示特定車/日,所有成員爲了。

SELECT * 
    FROM Members 
    WHERE Date=DATEADD(dd, 0, DATEDIFF(dd, 0, GetDate())) 
    AND CarId=1 
    ORDER BY Time -- new split col 

但也許它甚至更快的將它拆分了一些更多的使用

SELECT Id, Name 
FROM Car 
WHERE Id IN (
    SELECT CarId 
    FROM Members 
    WHERE Year=2014 
    AND Month=10 
    AND Day=2 
) 
+2

我懷疑分裂日期和時間可能實際上降低性能。你可以在你認爲有幫助的地方添加一個示例查詢,以便我們更好地理解動機或者可能提出一種替代方法? – 2014-10-02 08:23:08

+0

那麼從第一次開槍看起來好像不是問題,但是可以提供表格的數據結構和完整的查詢。還有,你有多少條記錄? – 2014-10-02 08:44:22

+0

更新的問題。大約100,000個記錄將每月添加到某些表中,因此如果沒有正確更改,性能將快速下降 – 2014-10-02 08:49:27

回答

0

我在下面提供了一些優化的SQL,但更多的信息將是有益的。此外,你的表和索引的DDL將有助於提供洞察力。

1)汽車今天帶動

select c.id, c.name 
from members as m 
inner join car as c 
on c.Id = m.CarId 
where 
    m.datetime < '2014-10-04 00:00:00' 
    and m.datetime >= '2014-10-03 00:00:00' 

-- you could pipe that date calculation into the genated sql 
-- or work with the getDate function and use ceiling 

where 
    m.datetime < DATEADD(day,1,CONVERT (date, GETDATE())) --tomorrow 
    and m.datetime >= CONVERT (date, GETDATE()) --today 

目前你的代碼doed永遠單列計算並沒有對搜索參數表現不佳(個SARG)

2)列表中的所有潛在的名單成員,特定的汽車和日期依次是:

select m.* 
from members as m 
where 
    m.carId = 1 
    and m.datetime < '2014-10-04 00:00:00' 
    and m.datetime >= '2014-10-03 00:00:00' 
order by m.datetime 

注:

I)日期時間被分割,然後對他們的限制過濾是不可取的

II)表的快速增長 - 它同時日期分區表或 較舊的數據移動到歷史表,所以你」可能是值得的只處理較小的數據集。

III)也許值得在插入時設置一個觸發器來創建一個名爲日期 的額外列,然後您可以查詢是否對應用程序查詢的方式有限制。請

其他信息:

我),你可以提供DDL關閉表和索引?

II)當前的行數,並依靠carid/ID不同/ MEMBERID