2011-11-02 61 views
1

在更改之前,我有一個持續計算字段,它使用Checksum函數和索引來使用它。SQL Server和持久計算字段與哈希字節

alter table Softs add TitleHash AS (CHECKSUM([Title])) PERSISTED; 

一切都很好,直到我們發現Checksum產生較差的散列並且可能發生重複。所以我們決定使用Hashbytes。 我都嘗試用二進制結果和焦炭結果

alter table Softs add TitleHashCBin AS (CONVERT(BINARY(16),hashbytes('MD4',[Title]))) PERSISTED; 

alter table Softs add TitleHashCChar AS (CONVERT(CHAR(32),hashbytes('MD4',[Title]),2)) PERSISTED; 

不幸的是,我們發現,一個簡單的SELECT請求新的現場使用索引。

SELECT id FROM Softs WHERE TitleHashCBin = 0xC29939F6149FD65100A66AF5FD958D8B 

它掃描主索引這是建立在Id柱。

之後,我們創建了二進制列,從TitleHashCBin複製數據,併爲新列創建索引。

alter table Softs add TitleHashBin AS Binary(16) 

並使用了類似的select語句。

SELECT id FROM Softs WHERE TitleHashBin = 0xC29939F6149FD65100A66AF5FD958D8B 

而這一次通過TitleHashBin字段使用索引。 計算字段到底是什麼。有人可以解釋我做錯了什麼,或者它是一個錯誤? P.S. Sql Server 2008 10.0.3798

編輯 我剛剛從表中刪除char列以調查SSMS生成的內容。它實際上與您所描述的相同。

BEGIN TRANSACTION 
SET QUOTED_IDENTIFIER ON 
SET ARITHABORT ON 
SET NUMERIC_ROUNDABORT OFF 
SET CONCAT_NULL_YIELDS_NULL ON 
SET ANSI_NULLS ON 
SET ANSI_PADDING ON 
SET ANSI_WARNINGS ON 
COMMIT 
BEGIN TRANSACTION 
GO 
--DROP INDEXes here 
--GO 
ALTER TABLE dbo.Softs DROP COLUMN TitleHashCChar, TitleHashChar 
GO 
ALTER TABLE dbo.Softs SET (LOCK_ESCALATION = TABLE) 
GO 
COMMIT 

所以我認爲我們可以假設表格選項是正確的。 之後,我反覆SELECT語句,但像以前那樣使用相同的執行計劃...

編輯 我決定使用簡單的二進制領域和插入/ UPDATE觸發器來更新他們的任務。奇蹟般有效。但是,目前還不清楚它爲什麼有這麼奇怪的行爲?..

回答

0

確保您的設置選項是正確的,從BOL Link

SET選項要求 的ANSI_NULLS連接級選項必須設置爲ON時,CREATE執行定義計算列的TABLE或ALTER TABLE語句。 OBJECTPROPERTY函數報告該選項是否通過IsAnsiNullsOn屬性打開。 創建索引的連接以及試圖改變索引值的INSERT,UPDATE或DELETE語句的所有連接必須將六個SET選項設置爲ON,並將一個選項設置爲OFF。優化程序會忽略由不具有相同選項設置的連接執行的任何SELECT語句的計算列上的索引。 的NUMERIC_ROUNDABORT選項必須設置爲OFF,且下列選項必須設置爲ON:

ANSI_NULLS

ANSI_PADDING

ANSI_WARNINGS

ARITHABORT

CONCAT_NULL_YIELDS_NULL

QUOTED_IDENTIFIER

將數據庫兼容級別設置爲80或更早版本時,將ANSI_WARNINGS設置爲ON會將ARITHABORT設置爲ON,如果數據庫兼容級別設置爲ON,則ARITHABORT選項必須顯式設置爲ON。有關更多信息,請參閱影響結果的SET選項。

+0

謝謝!我已經使用您提供的新信息更新了我的帖子。選項似乎是正確的,但不幸的結果是相同的... – Cheburek