SQL Server 查询计划哈希冲突

Dav*_*ims 1 sql-server execution-plan database-internals hashing

我想知道是否有人可以阐明我的担忧,即query_plan_hash碰撞可能导致查询作为完全不同的查询执行。

散列是一个 16 位的十六进制,sp_help sys.dm_exec_query_stats表示是一个二进制。因此它只是一个 64 位的散列,并且碰撞似乎很有可能(考虑到 SHA1 [160 位] 刚刚被验证有碰撞)。

请问plan_hashquery_plan_hash都有碰撞的这个(查询作为一个完全不同的查询被执行)的情况发生?

我也很好奇 SQL Server 中是否有设置允许我们将此哈希更改为 SHA2-512(以减少发生冲突的可能性)。我们的数据非常重要。

我通过 Google 和 Stack Exchange 论坛进行了高低搜索。

Pau*_*ite 7

既不query_hash也不query_plan_hash用于查找执行的查询计划,因此不会出现问题中的确切问题。

的文档sys.dm_exec_query_stats解释说:

  • query_hash提供允许用户聚合资源使用情况,这些查询仅在文字值(将参数化为相同形式的值)上有所不同。
  • query_plan_hash提供允许用户计算具有相似执行计划的查询的累积成本。

不出所料,SQL Server 开发人员竭尽全力确保缓存的计划仅在安全的情况下才能重用。这远远超出了缓存计划必须与“查询”完全匹配的明显要求。

简要地:

SQL Server 有多个计划缓存存储,每个都实现为一个哈希表。甲散列值高速缓存密钥对用于与特定的“查询”连接编译的计划。

哈希值(database_id * object_id) mod (hash table size)。这确定了特定缓存存储中的哈希桶。这object_id是过程、函数和触发器等对象的已知元数据。对于临时 SQL,它object_id是整个批处理文本的散列。

属性的集合必须为一个缓存计划来匹配“查询”匹配是被称为缓存键。这用于在哈希桶中查找和确认完全匹配。一些(不是全部)缓存键属性可以在sys.dm_exec_plan_attributes的文档中找到。

重要的是,对于临时 SQL,整个批处理文本是缓存键属性之一。


更多细节可以在 Microsoft SQL Programmability & API Development Team 的3.0 How Cache Lookups Work(以及该系列的其他文章)中找到。