如果我需要从数据库中检索一个大字符串,使用字符串本身搜索它是否更快,还是通过散列字符串并将数据存储在数据库中然后根据它进行搜索来获得?
如果是,我应该使用什么哈希算法(安全性不是问题,我正在寻找性能)
如果重要:我使用的是C#和MSSQL2005
答案 0 :(得分:5)
一般情况下:假设列已编入索引,可能不会。数据库服务器旨在快速有效地执行此类查找。某些数据库(例如Oracle)提供了基于散列构建索引的选项。
但是,最终只能通过具有代表性(您的要求)数据和使用模式的性能测试来解决。
答案 1 :(得分:3)
虽然我从来没有这样做过,但听起来这原则上是可行的。你有可能得到误报,但这可能很渺茫。
我会使用快速算法(例如MD5),因为您不希望花费更长时间来散列字符串,而不是仅仅搜索它。
我能说的最后一件事是,你只会知道如果你尝试一下并且衡量表现会更好。
答案 2 :(得分:3)
如果这提供了巨大的改进,我会感到惊讶,我建议不要使用自己的性能优化进行数据库搜索。
如果使用数据库索引,DBA可以使用经过尝试和信任的方法调整性能范围。对您自己的索引优化进行硬编码可以防止这种情况发生,并可能会阻止您在未来版本的数据库中获得索引性能的任何改进。
答案 3 :(得分:2)
首先 - 测量它。这是确定的唯一方法 第二 - 如果您对字符串搜索的速度没有问题,那么请保持简单,不要使用哈希。
然而,对于你的实际问题(并且只是因为它是一个有趣的想法)。这取决于字符串的相似程度。请记住,数据库引擎不需要比较字符串中的所有字符,只能找到差异。如果您正在查看1000个字符串,这些字符串都以相同的300个字符开头,那么哈希几乎肯定会更快。但是,如果您正在寻找以x开头的唯一字符串,那么字符串比较可能会更快。我认为虽然SQL仍然必须从光盘中获取整个字符串,即使它只使用第一个字节(或多字节字符的前几个字节),因此总字符串长度仍然会产生影响。
如果您正在尝试哈希比较,那么您应该将哈希设为索引计算列。如果你在每次运行查询时计算所有字符串的哈希值,它就不会更快!
您还可以考虑使用SQL的CRC功能。它产生一个int,它甚至可以更快地进行comapre并且计算速度更快。但是你必须通过实际测试字符串值来仔细检查这个查询的结果,因为CRC函数不是为这种用法而设计的,而且更有可能返回重复值。您需要在一个查询中执行CRC或散列检查,然后使用外部查询来比较字符串。您还需要观察生成的QEP,以确保优化器按照您预期的顺序处理查询。它可能决定先进行字符串比较,然后再进行CRC或Hash检查。
正如其他人所指出的那样,如果您正在进行完全匹配,这只会有任何好处。如果您尝试进行任何范围或部分匹配,哈希就无法帮助。
答案 4 :(得分:1)
如果使用固定长度字段和索引,它可能会更快......
答案 5 :(得分:1)
如果您的字符串很短(一般少于100个字符),字符串会更快。
如果字符串很大,HASH
搜索可能会更快。
HashBytes(MD4)
似乎是DML
上最快的。
答案 6 :(得分:1)
您正在进行相等匹配或包含匹配吗?对于相等匹配,您应该让db处理此问题(但添加非聚集索引)并仅通过WHERE table.Foo = @foo
进行测试。对于包含匹配,您应该查看full text index。
答案 7 :(得分:1)
提示:如果要将哈希值存储在数据库中,MD5哈希值总是16个字节,因此可以保存在uniqueidentifier列中(以及.NET中的System.Guid)
这可能会以不同的方式提供比保存哈希值更多的性能提升(我使用此方法检查二进制/ ntext字段更改,但不检查字符串/ nvarchars)。
答案 8 :(得分:1)
“理想”的答案肯定是肯定的。 与索引列匹配的字符串总是比匹配存储在索引列中的哈希值慢。这就是hashvalues的设计目标,因为它们采用大型数据集(例如3000个比较点,每个字符一个)并将其合并为较小的数据集(例如16个比较点,每个字节一个)。
因此,最优化的字符串比较工具将比优化的哈希值比较慢。
然而,正如已经指出的那样,实现自己的优化哈希函数是危险的,并且可能不顺利。 (我已经尝试过并且失败了)哈希冲突并不是特别的问题,因为那时你只需要回到字符串匹配算法,这意味着(最坏的情况下)与字符串比较方法一样快。
但是,这都假设您的散列以最佳方式完成(它可能不会)并且您的散列组件(将会出现)中没有任何错误以及性能增加将是值得的努力(可能不是)。字符串比较算法,尤其是索引列中的字符串比较算法已经非常快,并且散列工作量(程序员时间)可能远高于您可能的增益。
如果您想了解表现,请测量它。
答案 9 :(得分:0)
我很困惑,可能会误解你的问题。
如果你已经有了字符串(因此可以计算哈希),为什么需要检索它呢?
你是否使用大字符串作为某些东西的关键?