2011-11-02 48 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