【发布时间】:2012-12-12 22:38:12
【问题描述】:
我在表中有一个类型为 nvarchar(max) 的列,在某些情况下我需要对该列的内容执行完全匹配。
我知道我可以创建一个全文索引,从广义上讲,据我了解,它对文本进行标记,以便在想要在字符串中搜索时进行更有效的查询。我想知道,在执行完全匹配时,全文索引在提高性能方面是否真的有任何用处?
有没有更好的选择?
【问题讨论】:
标签: sql sql-server-2008 sql-server-2005
我在表中有一个类型为 nvarchar(max) 的列,在某些情况下我需要对该列的内容执行完全匹配。
我知道我可以创建一个全文索引,从广义上讲,据我了解,它对文本进行标记,以便在想要在字符串中搜索时进行更有效的查询。我想知道,在执行完全匹配时,全文索引在提高性能方面是否真的有任何用处?
有没有更好的选择?
【问题讨论】:
标签: sql sql-server-2008 sql-server-2005
如果您需要检查的只是完全匹配,您可以创建一个计算列,它是nvarchar(max) 字段的哈希值。
这将足够小,可以索引,但仍会指示字段是否完全匹配。
一般的想法是:
ALTER TABLE MyTable
ADD HashField as HASHBYTES('MD5', LongfieldName)
【讨论】:
我知道这是一个老问题,我会评论 JNK 的回答,但我没有代表这样做......
首先,由于您使用的是 Nvarchar,因此您必须非常小心,以确保在排序规则哈希中比较相等的字符串相等;除非您使用二进制排序规则,否则除非您的哈希算法支持 Unicode 或您首先规范化字符串,否则不会发生这种情况。 Unicode 允许相同字符的不同表示,例如 É 可以表示为代码点 U+00C9,或代码点 U+0045 (E) 后跟代码点 U+0301(组合锐音)。
其次,像 MD5 这样的加密散列算法不能很好地满足这里的需求,因为你在散列是为了性能而不是安全。您不需要在每次插入和每次查询开始时花费那么多 CPU,也不需要索引键那么大。你想要的是几乎 .NET StringComparer.GetHashCode() 函数,它速度很快,可以处理逻辑上但二进制不相等的字符,并生成一个小的哈希码,因此可以非常快速地进行比较。遗憾的是,MS 保留随意更改该算法的权利,这会破坏任何存储的哈希值。如果你还是要使用 CLR,我可能会建议从 Mono 项目中窃取适当的 GetHashCode 实现——他们的类库是 MIT 许可的,所以只要你在源代码中保留版权声明,你就可以随意提升它们。
【讨论】: