2010-01-15 23 views
1

我們有一個引用用戶表的密碼錶。記錄永遠不會從密碼錶中刪除,因此如果用戶更改其密碼,則會插入一個新條目,其中包含更新的Created日期。這是一個有效且高效的SQL查詢還是有更好的方法?

密碼的哈希被醃製的各種事情,最重要的實際記錄的創建日期。

在一個存儲過程中,我正在檢索變量,所以我可以做一個散列來進行比較。我真的只是想爲用戶最近的密碼哈希存儲與記錄的創建日期進行:

DECLARE @ExistingPassword as varchar(200) 
DECLARE @LastChanged as DateTime 

SELECT Top 1 
    @ExistingPassword = p.PasswordHash, 
    @LastChanged = p.Created, 
FROM Password as p 
WHERE p.UserId = @UserId 
ORDER BY p.Created DESC 

這是獲得最新的密碼哈希和創建日期的合理有效的方式?有沒有更好的方法來做到這一點?

+0

那完全取決於表的大小

userId and created 

,到位哪些索引以及指數如何分散。 –

+0

@Mitch - 是的,指出一點,這會產生很大的變化。作爲背景,我們正在討論可能有50,000個用戶,他們可以按照自己的喜好定期更改密碼。然而,隨着時間的推移,用戶最終可能會有幾百個密碼。 – Damovisa

回答

2

這是有效的,但我會確保有一個索引:由於性能原因

+0

+1。只要索引在那裏,「TOP 1 ORDER BY」將解析爲1行索引查找,這幾乎是您可以獲得的最快速度。只要確保索引是**覆蓋**(即'INCLUDE(ExistingPassword,LastChanged)')。 – Aaronaught

0

通過我個人的經驗,你應該用一段時間的工作,像StartDateEndDate。因此,您可以使用WHERE getdate() BETWEEN StartDate and EndDate來搜索您當前的密碼。

每次添加一條記錄只是爲後續的大部分更新檢索創建日期,嬰兒耶穌哭。

+0

困難在於用戶需求指定一個人的密碼不必過期(不是我的想法)。在這種情況下,沒有'EndDate'。 – Damovisa

+0

所以'@EndDate ='2199-12-31'',直到你得到一個新的,當你設置實際EndDate爲昨天和新的一個今天開始 –

+0

我明白你的意思,但這意味着任何插入必須插入一條新記錄並更新現有記錄以過期'EndDate' - 額外的工作。如果'@ EndDate'將來總是200年,那麼select查詢就會有一個額外的'WHERE EndDate <@ EndDate'子句,這是毫無意義的。很有用,如果我改變了我的做法,當然,但規範已經定義。 – Damovisa

1

我認爲這是最快的方法。我運行了下面的代碼來測試你的方式,而我唯一能想到的方式就是更快一點。我還想在一張有1,000,000行的表格中提到,我的響應時間足夠快,SSMS甚至沒有給我一個運行時間,只是00:00:00。我確實看到有一件事可能會對你有所幫助。如果可以,請在Created列上放置非聚集索引,並按降序排列。將其降序排列會產生很大的差異,因爲它會阻止您對最新的創建日期時間進行表掃描。這真的可以造成巨大的差異。

--Put Rows in TestTable, 3 Rows ID, User_ID, CreatedTime 
DECLARE @Count INT 
SET @Count = 1 

WHILE @Count <= 1000000 
BEGIN 

INSERT INTO TestTable 
VALUES (@Count%3+1,DATEADD(HH,@Count,getdate())) 

SET @Count = @Count + 1 

END 

--Select Your way 
SELECT TOP 1 
User_ID 
FROM TestTable 
WHERE User_ID = 3 
ORDER BY CreatedTime DESC 

--Select my way 
SELECT 
User_ID 
FROM TestTable 
WHERE User_ID = 3 
and CreatedTime = (SELECT MAX(CreatedTime) FROM TestTable WHERE User_ID = 3) 
+0

真棒,感謝基準測試工作! – Damovisa

相關問題