【问题标题】:SQL Server Hash IndexesSQL Server 哈希索引
【发布时间】:2008-11-25 17:32:26
【问题描述】:

当使用 CHECKSUM 列类型人为创建哈希索引时,查找实际上是 O(1) 还是仍然像聚集索引一样 O(lg n)?我有一个表,我将根据它的 ID 列从中选择,我需要尽可能快的查找,那么聚集索引是最快的选项吗?我正在寻找能够提供 O(1) 性能的东西。

【问题讨论】:

    标签: sql-server hash indexing


    【解决方案1】:

    好的,2 分。
    SQL CHECKSUM 函数不产生哈希值。它实际上计算了一个 CRC 值。基于哈希检查不是一个很好的候选,因为会有相对大量的冲突。如果你想要一个哈希函数,你应该检查 hash_bytes 函数。
    其次,您实际上并没有创建哈希索引。您在哈希值上创建普通 b-tree,因此查找时间将与类似大小数据类型上的任何其他 b-tree 索引完全相同。
    通过使用长 varchar 值的 CRC 或散列来允许比较较少的字节数,您有可能获得一点性能,但字符串比较只检查它需要的字节数,即第一个不匹配的字符,如果你在哈希值上匹配,那么无论如何你都需要仔细检查实际值。因此,除非您有很多非常相似的字符串,否则您最终可能会使用散列(或 CRC)比较更多字节。

    简而言之,我认为这不是一个明智的计划,但与所有优化一样,您应该在特定情况下对其进行测试,然后再决定。如果您愿意发布结果,我很想看看您的结果。而且我认为在 SQL Server 中定位行没有比使用聚集索引更快的方法。

    如果您关心,Ingres(由 CA)可以创建哈希索引,然后将达到 O(1)。可能还有其他 RDBM 也支持真正的哈希索引。

    【讨论】:

    • 我不同意。在您通过存储桶的数量对其中的某些部分进行 MOD 后,CRC 应该是相当随机的。我不明白你为什么认为会有“相对大量的碰撞”。
    • 为了测试,我刚刚检查了一列 11k 字符串(主要是 URL,所以有很多相等的初始段)上的冲突。使用 BINARY_CHECKSUM 我得到了 3 次 3 向碰撞和 5 次 2 向碰撞。正如你所料,使用 HASHBYTES 我没有得到任何结果,即使使用 MD2 也是如此。
    【解决方案2】:

    我不认为 SQL 服务器本身具有基于哈希表的索引。 BOL documentation 正在讨论在计算值上构建标准(树)索引。这与 Linear Hash Table 不同,后者是某些 DBMS 平台上可用的索引结构,但不是 SQL Server (AFAIK)。

    您可能会从使用this blog post 中描述的技术对大字符串值(例如 URL)进行散列以加快查找速度获得一些好处。但是,底层索引仍然是一个树结构,并且是 O(Log N)。

    【讨论】:

    • 更新:内存中的 SQL Server 表确实具有基于哈希表的索引功能。
    【解决方案3】:

    您可以尝试设置使用哈希联接,您可以查看执行计划以验证是否实际使用了哈希联接。使用散列连接时,SQL Server 仍将首先构建散列表作为执行单个查询的一部分。我相信索引永远不会存储为哈希,而只会存储为树。

    一般来说,除非您对潜在的大字符串或二进制 blob 进行精确匹配(如 pipTheGeek 所述),否则我不会创建人工哈希列。我只是想补充一点,有时这是必要的,因为字符串可能太大而无法放入索引键中。 SQL Server 的索引键大小有一个限制,我认为是 2k。

    当然,在您的联接中,您需要包含散列列和源列,以解决散列导致的任何歧义。

    【讨论】:

    • SQL Server 有一个900-byte limit 用于所有索引键列的最大总大小。
    【解决方案4】:

    如果 ID 字段是 int,则在 ID 字段上搜索索引 CHECKSUM 而不是聚集索引没有优势,因为两者都会执行聚集索引查找。此外,int 列的 CHECKSUM 始终返回与该列相同的值(即 CHECKSUM(535) = 535)。但是,如果 ID 是长字符列,则 CHECKSUM 查找通常会执行得更好。

    【讨论】:

    • 那么有什么方法可以实现比聚集索引更好的性能?聚集索引仍然是 O(lg n),我在寻找 O(1)..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    相关资源
    最近更新 更多