我有一個大致包含1,000,000行,由約10萬條記錄成長下面的「PriceData」數據庫表/日:SQL服務器,請選擇要及時返回最新的紀錄
Id | DateCreated |TradeDate |fk_Currency | Price
--------------------------------------------------------------
48982| YYYYMMDDhhmmss | YYYYMMDDhhmmss |1 | 1.09684
48953| YYYYMMDDhhmmss | YYYYMMDDhhmmss |1 | 1.22333
48954| YYYYMMDDhhmmss | YYYYMMDDhhmmss |2 | 1.22333
我要求的任務我一定要能夠獲取最新的價格對於一個給定的貨幣輸入,下面的存儲過程實現了這一點,但花費太長時間來執行(3.4秒):
PROCEDURE [dbo].[GetRecentPrice] @currency nvarchar(6)
SELECT Price from PriceData
WHERE Id = (SELECT MAX(Id) FROM PriceData
WHERE fk_CurrencyPair = (SELECT Id FROM CurrencyPair WHERE Name = @currency));
SQL Server的執行時間:CPU時間= 78毫秒,經過時間= 3428毫秒。
我試過,包括下面的where子句只檢查數據的前一分鐘:
AND TradeDate >= (SELECT (DATEADD(MINUTE, -1, (SELECT CONVERT(datetime, SYSDATETIMEOFFSET() AT TIME ZONE 'Central Standard Time'))))
但它只有大約700毫秒帶來的執行時間下來:
CPU時間= 62毫秒,經過時間= 2762毫秒。
我也考慮過創建一個只存儲每種貨幣最近價格的新表格,只要PriceData表格中有新的價格就更新。但是,這感覺像一個骯髒的黑客攻擊,我肯定違反了一些數據庫規範化原則。
該存儲過程由一個MVC應用程序使用的Web服務層執行,因此執行時間需要更好(我想讓它達到< 100毫秒)。我願意修改此表和數據庫的體系結構。
謝謝。關於指數; SQL Server默認在相應的主鍵上包含聚簇索引。這些索引是否足夠用於我的用例? – slashNburn
@slashNburn yup,如果你已經在ID字段上創建了主鍵,那麼已經在該字段上創建了聚集索引。但是,如果將排序順序設置爲「DESC」,則不需要使用order by子句,只需將id字段置於select語句中即可。 – Shell
@Giorgos Betsos:非常感謝你對這個非常優雅的答案的幫助。 SQL Server執行時間: CPU時間= 0毫秒,經過時間= 2毫秒 – slashNburn