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 和带有哈希字节的持久计算字段的主要内容,如果未能解决你的问题,请参考以下文章
如何将两个不同数据库(MySQL、SQL SERVER)之间的 TEXT 字段与哈希值进行比较?
SQL Server-聚焦计算列或计算列持久化查询性能(二十二)
带有实体框架和 SQL Server 数据库的 ASP.NET MVC - 图像未显示在视图中......错误显示“无法将“字节”转换为“字符串”