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

Posted

技术标签:

【中文标题】在 SQL Server 数据库中计算字符串的哈希值 - 值得付出努力吗?【英文标题】:Computing hashes for strings in SQL Server database - worth the effort? 【发布时间】:2009-03-30 23:48:27 【问题描述】:

假设我的 SQL Server 2005 数据库中有一个百万行表 [mytable],其中包含列:

身份证 一些领域 另一个领域 网址

这个系统中一个很常见的查询是:

select * from [mytable] where url = 'http://www.somesite.com/some/really/long/url'

这会给我带来更好的性能:

a) 为 Url 列添加索引。

b) 添加一个额外的“url_hash”列,其中包含与 url 对应的数字哈希,然后计算该哈希以在我的 where 子句中使用,例如:

select * from [mytable] where url_hash = some-computed-hash and url = 'http://www.somesite.com/some/really/long/url'

(b)值得额外的复杂性吗?我需要计算插入和选择的哈希值。

2009 年 3 月 30 日更新

ID是主键

另外,上面的查询不应该有“*”。相反,选择列表应该是表中的所有字段。

"*" 只是简写 - 很抱歉造成混淆。

2009 年 3 月 31 日更新

另外,忘了提一下,url_hash 字段上会有一个索引。

【问题讨论】:

这可能需要半个小时来构建和测试。 【参考方案1】:

如果您只选择您需要的列(与“*”相反),并在“Url”和所选列上创建覆盖非聚集索引,您将获得非常有效的查找。

【讨论】:

【参考方案2】:

简单来说,一个字符串越长,两个字符串越相似,比较它们所需要的时间就越长(考虑一个1000个字符长的字符串,唯一的区别是最后一个字符,你可以看到它会多长时间在例行程序发现差异之前采取)。

但是,让我们将比较长字符串的成本与在磁盘上定位它们的成本进行对比。

索引存储在 B+Trees 中,它们是具有可变数量节点的平衡树,并且每个节点都链接到另一个节点 (a -> b -> c)。这为我们提供了两个功能:通过遍历树快速查找,然后快速按树顺序访问其他节点(一旦找到“a”,就很容易找到“b”,然后是“c”,等等)。

索引在磁盘页面中布局,通常可以塞入索引页面的节点越多,索引 B+tree 的整体高度就越低。树的高度越低,您找到特定行的速度就越快,因为您通常会遍历树的高度(因为它是平衡的)以到达任何一个叶节点。

高度越低,您必须进行的磁盘撞击就越少。如果你有一棵 4 高的树,那么要到达任何随机节点都需要将 4 个索引页加载到 RAM 中,这就是 4 个磁盘命中。因此,一棵 4 高的树的效率是一棵 8 高的树的“两倍”(对于“两倍”的各种值)。

此外,您可以在索引页面中添加的内容越多,如果您开始沿节点进行迭代,您需要的点击次数就越少。如果您的节点拥有 10 个键值,则加载 100 行将花费您 10 次索引页面命中,而如果每个节点仅保留 5 个,您将获得两倍的索引磁盘命中。

请注意,就需要向树中添加新层的记录数而言,您会得到几何级数。 (即5个关键节点和10个关键节点之间的差异不是记录的两倍。)

所以,这就是拥有小键的价值——索引树中的大量扇出。

请注意,使用哈希,您仍然需要执行“where hash = and url='...'”。

但说实话,这真的取决于您的数据访问模式。数据库有多忙,你做了什么样的查询,你需要多少内存来缓存索引页等等。

定位您的初始行的索引命中可能甚至不在您的查询时间的雷达上。

关键点是记录的数量并不重要,但索引树的扇出很重要。例如,如果你有一个 1K 的索引节点和一个 4 字节的索引(long int),你可以得到每个索引 250 个节点(这里非常简单),一个 3 层树可以得到,什么,16M 行都在一个3 深树 - 3 个磁盘命中内的 16M 行中的任何一个。

【讨论】:

所以听起来你说 SO 有一个合理的担忧,因为它们的键域很长,所以应该花时间研究这个策略,因为它可能会缩短查询时间?换句话说,您是在鼓励这种设计? 我只是指出他的决定的后果。我认为他应该尝试两种方法,看看一种方法是否比另一种方法性能显着提高,获取更多数据。与其他一切“取决于”。【参考方案3】:

即使您为 URL 计算哈希码,除非您为哈希码列添加索引,否则您不会获得非常好的性能,因此最好只在 URL 列上添加索引。

【讨论】:

【参考方案4】:

这是描述您在实际应用程序中使用真实表时遇到的实际问题,还是您正在寻找一种您不知道是否需要的优化?

如果不是 #1,那么我建议您索引 url,然后处理应用程序的其余部分,直到遇到问题(这不太可能)。

【讨论】:

以上是关于在 SQL Server 数据库中计算字符串的哈希值 - 值得付出努力吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 2008 中转换文本字符串中的哈希密码

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

[Sql-Server]密码盐和哈希值使用啥数据类型以及啥长度?

SQL Server 2008 中嵌套循环连接和哈希连接的区别

Sql Server 计算某个字符 在字符串中有多少

如何在 SQL Server 中计算字符串表达式?