使用查询哈希值来识别查询中的模式和趋势¶
若要识别、分组和分析查询历史记录中的类似查询,可以使用查询文本的哈希值。例如,您可以:
按查询哈希值对查询进行分组,以识别高开销的查询中的模式。
确定性能改进(例如,对群集密钥的更改)对重复查询的影响。
在以下视图和表函数中,您可以使用 query_hash
和 query_parameterized_hash
列来获取查询文本的哈希值:
ACCOUNT_USAGE 视图(保留 1 年)
INFORMATION_SCHEMA 表函数(保留 7 天)
QUERY_HISTORY 表函数
TASK_HISTORY 表函数
您可以使用此哈希值来分析重复的查询。
使用查询的哈希值 (query_hash
)¶
query_hash
列包含根据 SQL 语句的规范化文本计算的哈希值。具有完全相同查询文本的重复查询具有相同的 query_hash
值。
如果重复查询的查询文本仅在以下方面有所不同,则重复查询也具有相同的 query_hash
值:
不区分大小写的标识符、会话变量和暂存区名称
请注意,这不包括组合使用 IDENTIFIER() 与绑定变量来指定的标识符。具有不同值的绑定变量会产生不同的查询哈希值。
空格
注释
如果两个查询的查询文本有任何其他部分不同,则这两个查询具有不同的 query_hash
值。
例如,以下查询具有相同的 query_hash
值,因为它们具有完全相同的查询文本。
SELECT * FROM table1 WHERE table1.name = 'TIM'
SELECT * FROM table1 WHERE table1.name = 'TIM'
通过使用 query_hash
值,可以在查询性能中找出以其他方式难以发现的模式。例如,尽管查询在单次执行期间的开销可能不会过高,但频繁重复执行的查询可能会导致高成本,具体取决于其运行次数。您可以使用 query_hash
值来识别要首先重点优化的查询。
例如,以下查询使用 query_hash
值来识别运行时长排名前 100 的查询的查询 IDs:
SELECT
query_hash,
COUNT(*),
SUM(total_elapsed_time),
ANY_VALUE(query_id)
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE warehouse_name = 'MY_WAREHOUSE'
AND DATE_TRUNC('day', start_time) >= CURRENT_DATE() - 7
GROUP BY query_hash
ORDER BY SUM(total_elapsed_time) DESC
LIMIT 100;
使用参数化查询的哈希值 (query_parameterized_hash
)¶
query_parameterized_hash
包含根据参数化的查询(即字面量参数化后的查询版本)计算的哈希值。这些字面量必须在查询谓词中使用,并且必须与以下某个 比较运算符 结合使用:
=
(等于)!=
(不等于)>=
(大于或等于)<=
(小于或等于)
重复查询(包括具有不同参数值的重复查询)具有相同的 query_parameterized_hash
值。
如果重复查询的查询文本仅在以下方面有所不同,则重复查询也具有相同的 query_parameterized_hash
值:
不区分大小写的标识符、会话变量和暂存区名称
请注意,这不包括组合使用 IDENTIFIER() 与绑定变量来指定的标识符。具有不同值的绑定变量会产生不同的查询哈希值。
空格
注释
具有相同 query_hash
值的查询也具有相同的 query_parameterized_hash
值,反之则不然。
例如,以下查询具有相同的 query_parameterized_hash
值,因为字面量值是这两个查询之间的唯一不同之处:
SELECT * FROM table1 WHERE table1.name = 'TIM'
SELECT * FROM table1 WHERE table1.name = 'AIHUA'
与使用 query_hash
值的情况一样,您可以使用 query_parameterized_hash
值在查询性能中找出以其他方式难以发现的模式。
以下语句计算具有特定 query_parameterized_hash
值 (cbd58379a88c37ed6cc0ecfebb053b03
) 的所有查询的每日平均 total_elapsed_time
:
SELECT
DATE_TRUNC('day', start_time),
SUM(total_elapsed_time),
ANY_VALUE(query_id)
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE query_parameterized_hash = 'cbd58379a88c37ed6cc0ecfebb053b03'
AND DATE_TRUNC('day', start_time) >= CURRENT_DATE() - 30
GROUP BY DATE_TRUNC('day', start_time);
检查用于生成哈希值的版本¶
随着时间的推移,Snowflake 用于生成查询哈希值的逻辑可能会发生变化。对此逻辑的更改可能会导致为同一查询生成不同的哈希值。例如,对于给定的查询,逻辑版本 1 生成的哈希值可能与逻辑版本 2 生成的哈希值不同。
包含 query_hash
和 query_parameterized_hash
列的视图和表函数输出还包含以下列,这些列指定用于生成哈希值的逻辑版本:
query_hash_version
query_parameterized_hash_version
这些列中的版本号为 NUMBER(例如,逻辑的第一个版本为 1
,逻辑的第二个版本为 2
,等等)。
如果这些列在不同的时间段包含不同的版本号,则可以使用这些版本列来识别同一查询的不同哈希值。例如:
...
WHERE (query_hash = 'hash_from_v1' AND query_hash_version = 1)
OR (query_hash = 'hash_from_v2' AND query_hash_version = 2)