标签: hashing

使用 SQL CLR 标量函数模拟 HASHBYTES 的可扩展方式是什么?

作为 ETL 过程的一部分,我们将暂存中的行与报告数据库进行比较,以确定自上次加载数据以来是否有任何列实际发生了更改。

比较基于表的唯一键和所有其他列的某种散列。我们目前使用HASHBYTESSHA2_256算法,并发现如果许多并发工作线程都在调用HASHBYTES.

在 96 核服务器上进行测试时,以每秒哈希数衡量的吞吐量不会增加超过 16 个并发线程。我通过将并发MAXDOP 8查询的数量从 1更改为12 来进行测试。测试MAXDOP 1显示了相同的可扩展性瓶颈。

作为一种解决方法,我想尝试 SQL CLR 解决方案。这是我试图说明要求的尝试:

  • 该函数必须能够参与并行查询
  • 函数必须是确定性的
  • 该函数必须接受一个NVARCHARVARBINARY字符串的输入(所有相关列都连接在一起)
  • 字符串的典型输入大小为 100 - 20000 个字符。20000 不是最大值
  • 哈希冲突的几率应该大致等于或优于 MD5 算法。CHECKSUM对我们不起作用,因为冲突太多。
  • 该函数必须在大型服务器上很好地扩展(每个线程的吞吐量不应随着线程数量的增加而显着降低)

对于 Application Reasons™,假设我无法保存报告表的哈希值。这是一个不支持触发器或计算列的 CCI(还有其他我不想讨论的问题)。

HASHBYTES使用 SQL CLR 函数进行模拟的可扩展方式是什么?我的目标可以表示为在大型服务器上每秒获得尽可能多的哈希值,因此性能也很重要。我对 CLR 很糟糕,所以我不知道如何做到这一点。如果它激励任何人回答,我计划尽快为这个问题添加赏金。下面是一个示例查询,它非常粗略地说明了用例:

DROP TABLE IF EXISTS #CHANGED_IDS;

SELECT stg.ID INTO #CHANGED_IDS
FROM (
    SELECT ID,
    CAST( HASHBYTES ('SHA2_256', 
        CAST(FK1 AS NVARCHAR(19)) + 
        CAST(FK2 AS NVARCHAR(19)) …
Run Code Online (Sandbox Code Playgroud)

sql-server etl sql-clr hashing sql-server-2016

31
推荐指数
4
解决办法
1948
查看次数

在 HashBytes 函数中选择正确的算法

我们需要创建 nvarchar 数据的哈希值以进行比较。T-SQL 中有多种哈希算法可用,但在这种情况下,最好选择哪一种?

我们希望确保两个不同的 nvarchar 值具有重复哈希值的风险最小。根据我对互联网的研究,MD5 似乎是最好的。那正确吗?MSDN 告诉我们(下面的链接)有关可用算法的信息,但没有说明哪一种适用于什么条件?

哈希字节 (Transact-SQL)

我们需要在两个 nvarchar(max) 列上连接两个表。可以想象,执行查询需要很长时间。我们认为最好保留每个 nvarchar(max) 数据的散列值并对散列值进行连接,而不是 nvarchar(max) 值是 blob。问题是哪种哈希算法提供了唯一性,这样我们就不会遇到一个哈希值对应多个 nvarchar(max) 的风险。

sql-server t-sql sql-server-2008-r2 hashing

22
推荐指数
2
解决办法
2万
查看次数

redis 新手 - 如何在散列中创建散列?

我想在redis中创建这种类型的结构:(它基本上是json数据)

{
    "id": "0001",
    "name":"widget ABC",
    "model": "model123",
    "service":"standard",
    "admin_password": 82616416,
    "r1":
        {
            "extid":"50000",
            "password":"test123",
        },
    "r2":
        {
            "ext":"30000",
            "password":"test123",
        },
}
Run Code Online (Sandbox Code Playgroud)

到目前为止我尝试过的:

我试图创建一个没有“子”哈希的哈希,只是为了确保我掌握了基本知识。所以这是我从 redis-cli 开始的:

HMSET widget:1 id 0001 name 'widget ABC' model 'model123' service standard admin_password 82616416
HMSET widget:2 id 0002 name 'widget ABC' model 'model123' service standard admin_password 12341234
Run Code Online (Sandbox Code Playgroud)

这似乎有效。我可以看到我在小部件集合中有 2 条小部件数据“记录”。

但是我尝试使用 r1 数据创建记录失败。

这是我尝试过的:

HMSET widget:3 id 0002 name 'widget ABC' model 'model123' service standard admin_password 12341234 r1{extid 50000} 
Run Code Online (Sandbox Code Playgroud)

这将创建一个散列值“50000}”的散列键“r1{extid”

任何建议,将不胜感激。我认为我的问题是我的行话。我只是不太了解 redis 语法,无法知道在我的谷歌搜索中使用哪些词。

也许我只需要像这样“展平”数据:

HMSET …
Run Code Online (Sandbox Code Playgroud)

nosql redis hashing

16
推荐指数
1
解决办法
2万
查看次数

对于等式查找,Hash Index 怎么可能不比 Btree 快?

对于每个支持哈希索引的 Postgres 版本,都有一个警告或说明哈希索引与btree索引“相似或更慢”或“不更好” ,至少到版本 8.3。从文档:

7.2 版

注意:由于哈希索引的实用性有限,B 树索引通常比哈希索引更受欢迎。我们没有足够的证据表明即使对于 = 比较,哈希索引实际上也比 B 树更快。此外,哈希索引需要更粗的锁;见第 9.7 节。

7.3 版(最高 8.2 版)

注意:测试表明 PostgreSQL 的哈希索引B 树索引相似或更慢,并且哈希索引的索引大小和构建时间要差得多。哈希索引在高并发下也表现不佳。由于这些原因,不鼓励使用哈希索引。

8.3 版

注意:测试表明 PostgreSQL 的哈希索引的性能并不比 B 树索引好,哈希索引的索引大小和构建时间要差得多。此外,哈希索引操作目前没有 WAL 日志记录,因此在数据库崩溃后可能需要使用 REINDEX 重建哈希索引。由于这些原因,目前不鼓励使用哈希索引。

在这个 8.0 版本的线程中,他们声称从未发现哈希索引实际上比 btree 更快的情况。

根据这篇博文(2016 年 3 月 14 日):André Barbosa撰写的
Postgres 上哈希索引,即使在 9.2 版本中,除了编写实际索引之外,任何其他方面的性能提升几乎都没有。

我的问题是这怎么可能?

根据定义,哈希索引是一种O(1)操作,而 …

postgresql index btree hashing

11
推荐指数
3
解决办法
6187
查看次数

EXCEPT 运算符背后的算法是什么?

在 SQL Server 中,Except运算符如何在幕后工作的内部算法是什么?它是否在内部获取每一行的哈希值并进行比较?

David Lozinksi 进行了一项研究,SQL:在不存在新记录的地方插入新记录的最快方法他表明,对于大量行,Except 语句是最快的;与我们下面的结果密切相关。

假设:我认为 Left join 会最快,因为它只比较 1 列,Except 花费的时间最长,因为它必须比较所有列。
有了这些结果,现在我们的想法是,Except 自动并在内部获取每一行的哈希值?我查看了除非执行计划,它确实使用了一些哈希。

背景:我们的团队正在比较两个堆表。表 A 不在表 B 中的行被插入到表 B 中。

堆表(来自旧文本文件系统)没有主键/guids/标识符。有些表有重复的行,所以我们找到每一行的Hash,并去除重复,并创建主键标识符。

1)首先我们运行一个except语句,排除(哈希列)

select * from TableA
Except
Select * from TableB,
Run Code Online (Sandbox Code Playgroud)

2)然后我们在HashRowId上的两个表之间运行左连接比较

select * 
FROM dbo.TableA A
left join dbo.TableB B
    on A.RowHash =  B.RowHash
where B.Hash is null
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,Except Statement Insert 是最快的。

结果实际上与 David Lozinksi 的测试结果接近

在此处输入图片说明

performance sql-server hashing sql-server-2016 except performance-tuning

10
推荐指数
1
解决办法
747
查看次数

哈希聚合救助

在聊天讨论中出现的一个问题:

我知道散列连接救助在内部切换到某种嵌套循环。

SQL Server 为散列聚合救助做了什么(如果它可以发生的话)?

sql-server aggregate execution-plan database-internals hashing

10
推荐指数
1
解决办法
381
查看次数

哈希联接与哈希半联接

PostgreSQL 9.2

我试图了解Hash Semi Join和 just之间的区别Hash Join

这里有两个查询:

一世

EXPLAIN ANALYZE SELECT * FROM orders WHERE customerid IN (SELECT
customerid FROM customers WHERE state='MD');

Hash Semi Join  (cost=740.34..994.61 rows=249 width=30) (actual time=2.684..4.520 rows=120 loops=1)
  Hash Cond: (orders.customerid = customers.customerid)
  ->  Seq Scan on orders  (cost=0.00..220.00 rows=12000 width=30) (actual time=0.004..0.743 rows=12000 loops=1)
  ->  Hash  (cost=738.00..738.00 rows=187 width=4) (actual time=2.664..2.664 rows=187 loops=1)
        Buckets: 1024  Batches: 1  Memory Usage: 7kB
        ->  Seq Scan on customers  (cost=0.00..738.00 rows=187 width=4) (actual …
Run Code Online (Sandbox Code Playgroud)

postgresql join hashing

9
推荐指数
1
解决办法
3355
查看次数

存储 HASHBYTES('MD5', ...) 结果的最佳数据类型

存储结果的最佳数据类型是HASHBYTES('MD5', ...)什么?

它输出 16 字节的二进制如下:例如

0x5CFCD77F9FF836189D2F647EBCEA183E
Run Code Online (Sandbox Code Playgroud)

我可以将它存储在以下数据类型中:

  • char(34)
  • binary(16)(我认为 - 我在这里读到(/sf/ask/1030561381/#16680423)使用相同的算法应该返回无论输入字符串如何,每次都具有相同数量的字节)
  • 其他?

每行都有一个值(没有空值),并且该列将用于与另一个表中的类似列进行比较。

哪种数据类型用于存储HASHBYTES上述使用的输出的最佳数据类型?

我在想,因为固定长度的数据类型有时在连接等方面可能更有效。binary(16)vs varbinary(8000)(的默认输出HASHBYTES)似乎最好,而binary(16)vs avarchar(34)更好,因为它会使用更少的存储空间。

sql-server datatypes sql-server-2014 hashing

8
推荐指数
1
解决办法
1万
查看次数

左散列连接总是比左外连接更好吗?

我有一个运行速度很慢的查询(见下文)。同时寻找改善它的方式,我们发现,约十倍,如果我们更换了更快的查询运行LEFT OUTER JOINLEFT JOIN HASH

结果似乎是一样的。是吗?在什么情况下它不会返回相同的结果?有什么区别?在运行 LEFT HASH JOIN 而不是 LEFT OUTER JOIN 时,有什么我应该注意的吗?

查询中的[ABC].[ExternalTable]表是我添加为外部表的另一台服务器上的视图

SELECT t.foo, t.bar, t.data
FROM [dbo].[Table] as t
LEFT OUTER JOIN [ABC].[ExternalTable] as s ON s.foo = t.foo and s.bar = t.bar and s.data = t.data
WHERE s.foo is null and s.bar IS NULL and s.data IS NULL
Run Code Online (Sandbox Code Playgroud)

sql-server hashing

7
推荐指数
3
解决办法
2349
查看次数

使用 HASHBYTES() 对 nvarchar 和变量产生不同的结果

我使用服务器端散列来传输密码,然后在数据库中运行 PBKDF2 来存储散列密码 + 盐组合。

散列nvarchar(max)@variable持有相同值的HASHBYTES()函数会产生不同的结果。

DECLARE @hash NVARCHAR(MAX) = 'password5baa61e4c9b93f3f0682250b6'

SELECT HASHBYTES('SHA1', 'password5baa61e4c9b93f3f0682250b6') AS NVARCHAR_INPUT, 
       HASHBYTES('SHA1', @hash) AS VARIABLE_INPUT
Run Code Online (Sandbox Code Playgroud)

产生以下结果:

NVARCHAR_INPUT                             | VARIABLE_INPUT
0xA03BEF0E3EC96CC7C413C6646D3FEC6174DA530F | 0x74B55C42E1E0AB5C5CDF10B28567590B240355C3
Run Code Online (Sandbox Code Playgroud)

这是 SQL Server 2012。这个特定的数据库正在运行 SQL Server Express,所以我也很好奇这个问题是否与版本无关。

sql-server t-sql sql-server-2012 encoding hashing

6
推荐指数
1
解决办法
7689
查看次数