SQL Server 和带有哈希字节的持久计算字段

Posted

技术标签:

【中文标题】SQL Server 和带有哈希字节的持久计算字段【英文标题】:SQL Server and Persisted computed field with Hashbytes 【发布时间】:2011-11-02 12:33:34 【问题描述】:

在更改之前,我有一个使用 Checksum 函数和索引来使用它的持久计算字段。

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

一切都很好,直到我们发现校验和产生的哈希值很差并且可能会出现重复。所以我们决定使用 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 字段的索引。 计算字段到底是怎么回事。有人可以解释我做错了什么还是一个错误? 附言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 语句,但执行计划与之前相同......

编辑 我决定使用简单的二进制字段和插入/更新触发器来更新它们。奇迹般有效。但目前还不清楚为什么它会有如此奇怪的行为?..

【问题讨论】:

【参考方案1】:

确保您的设置选项正确,来自BOL Link

SET 选项要求 执行定义计算列的 CREATE TABLE 或 ALTER TABLE 语句时,必须将 ANSI_NULLS 连接级别选项设置为 ON。 OBJECTPROPERTY 函数通过 IsAnsiNullsOn 属性报告选项是否打开。 在其上创建索引的连接,以及所有尝试 INSERT、UPDATE 或 DELETE 语句以更改索引中的值的连接,必须将六个 SET 选项设置为 ON,一个选项设置为 OFF。对于由不具有这些相同选项设置的连接执行的任何 SELECT 语句,优化器将忽略计算列上的索引。 NUMERIC_ROUNDABORT 选项必须设置为 OFF,以下选项必须设置为 ON:

ANSI_NULLS

ANSI_PADDING

ANSI_WARNINGS

阿里萨博特

CONCAT_NULL_YIELDS_NULL

QUOTED_IDENTIFIER

当数据库兼容级别设置为 90 时,将 ANSI_WARNINGS 设置为 ON 会隐式将 ARITHABORT 设置为 ON。如果数据库兼容级别设置为 80 或更早,则必须将 ARITHABORT 选项显式设置为 ON。有关详细信息,请参阅影响结果的 SET 选项。

【讨论】:

谢谢!我已经用你的新信息更新了我的帖子。选项似乎是正确的,但不幸的是结果是一样的......

以上是关于SQL Server 和带有哈希字节的持久计算字段的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server-聚焦计算列持久化(二十一)

如何将两个不同数据库(MySQL、SQL SERVER)之间的 TEXT 字段与哈希值进行比较?

SQL Server-聚焦计算列或计算列持久化查询性能(二十二)

SQL Server 2005 计算列被持久化

带有实体框架和 SQL Server 数据库的 ASP.NET MVC - 图像未显示在视图中......错误显示“无法将“字节”转换为“字符串”

在 SQL Server 数据库中计算字符串的哈希值 - 值得付出努力吗?