追踪SQL函数在Hasura中查询缓慢,直接执行SQL耗时极短
以下是针对性的排查方向:
检查Hasura实际生成的SQL语句
用Hasura的GraphiQL界面的Analyze功能,或者开启Hasura的调试日志(设置环境变量HASURA_GRAPHQL_LOG_LEVEL=debug),获取Hasura发送给PostgreSQL的完整SQL。和你直接执行的SQL对比,重点看:参数类型是否匹配(避免隐式转换导致索引失效)、Hasura是否自动添加了额外的过滤/排序逻辑、是否有__typename这类无关字段触发不必要计算。验证函数的稳定性属性
PostgreSQL的函数稳定性标记(VOLATILE/STABLE/IMMUTABLE)会直接影响优化器决策。如果函数标记为VOLATILE,Hasura调用时可能无法利用缓存或优化,而直接执行时优化器能做出更优选择。
执行这条SQL检查函数属性:SELECT proname, provolatile FROM pg_proc WHERE proname = 'your_function_name';如果函数结果不随事务上下文变化,改成
STABLE;如果结果仅依赖输入参数,改成IMMUTABLE。排查Hasura的缓存与权限逻辑
Hasura默认缓存查询结果,但如果函数有副作用或参数高频变化,缓存可能未生效。另外,Hasura对跟踪的函数会做权限校验,检查是否给该函数添加了不必要的过滤规则。
可以在GraphiQL的查询前加-- no-cache指令,测试是否是缓存问题;或者暂时关闭该函数的权限规则,看性能是否改善。对比PostgreSQL会话参数
Hasura的连接池使用的会话参数(比如work_mem、search_path、default_statistics_target)可能和你本地客户端不同,这些参数会影响执行计划的生成。
在Hasura中执行SHOW ALL;,和你本地客户端的会话参数对比,重点排查优化相关的参数差异。捕获Hasura调用时的执行计划
用PostgreSQL的pg_stat_statements扩展跟踪慢查询,获取Hasura调用时的实际执行计划,和直接执行的计划对比。
执行这条SQL查看相关统计:SELECT query, calls, total_time, mean_time, plan FROM pg_stat_statements WHERE query LIKE '%your_function_name%';重点看是否存在索引未命中、低效连接方式(比如嵌套循环代替哈希连接)、重复扫描等问题。
检查Hasura的函数跟踪配置
确认Hasura中跟踪该函数时的配置:是否开启了不必要的权限过滤、返回类型是否被正确解析、是否添加了多余的返回字段。尝试重新跟踪该函数,确保配置简洁匹配函数实际返回结构。
内容的提问来源于stack exchange,提问作者sourabh kumawat

