具有 LEFT JOIN 的 Postgres 服务器端游标不会在 Heroku PG 上返回

发布于 2025-01-09 18:50:16 字数 1210 浏览 0 评论 0原文

我有一个使用 psycopg 服务器端光标 以及在 Heroku PG 13.5 上运行的 LEFT JOIN 查询。

该查询基本上是“从一个表中获取未出现在另一表中的项目”。

我的数据量相当稳定,并且已经运行良好一段时间了。

本周这些查询停止返回。在 pg_stat_activity 中,它们无限期地显示为 active(超过 17 小时),与 heroku pg:ps 中类似。似乎没有出现僵局。所有 Heroku 数据库指标和日志均显示正常。

如果我直接在控制台中运行相同的查询(没有光标),它们会在几秒钟内返回。

通过提高查询效率(从 LEFT JOIN 切换到 NOT EXISTS;删除其中一个连接),我能够在游标中再次运行它。

我的问题是:

  • 为什么原始查询在控制台中执行良好,但不返回 psycopg 服务器端游标?
  • 我该如何调试这个?
  • 本周可能发生了什么变化而引发了这个问题?

我可以说:

  • 但是我编写查询(LEFT JOIN、子查询、NOT EXISTS),查询计划涉及嵌套循环反连接
  • 我不相信这是与第二天的 Heroku 中断相关(并且不影响 Heroku PG)
  • 在 Google 上进行了大量搜索后,我能找到的最接近解释这一点的假设是 2003 年 PG 留言板上的一篇帖子,标题为 左连接光标,其中响应是“某些计划节点类型不能很好地应对向后跑。”

任何建议表示赞赏!

I have a Heroku app that uses a psycopg server-side cursor together with a LEFT JOIN query running on Heroku PG 13.5.

The query basically says “fetch items from one table, that don’t appear in another table”.

My data volume is pretty stable, and this has been working well for some time.

This week these queries stopped returning. In pg_stat_activity they appeared as active indefinitely (17+ hours), similarly in heroku pg:ps. There appeared to be no deadlocks. All the Heroku database metrics and logs appeared healthy.

If I run the same queries directly in the console (without a cursor) they return in a few seconds.

I was able to get it working again in the cursor by making the query a bit more efficient (switching from LEFT JOIN to NOT EXISTS; dropping one of the joins).

My questions are:

  • Why might the original query perform fine in the console, but not return with a psycopg server-side cursor?
  • How might I debug this?
  • What might have changed this week to trigger the issue?

I can say that:

  • However I write the query (LEFT JOIN, Subquery, NOT EXISTS), the query plan involves a Nested Loop Anti Join
  • I don’t believe this is related to the Heroku outage the following day (and which didn’t affect Heroku PG)
  • Having Googled extensively, the closest thing I can find to a hypothesis to explain this is a post on the PG message boards from 2003 entitled left join in cursor where the response is “Some plan node types don't cope very well with being run backwards.”

Any advice appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

攒一口袋星星 2025-01-16 18:50:16

如果您使用游标,PostgreSQL 估计只有 10% 的查询结果会被快速获取,并且更喜欢快速返回前几行的计划,但代价是总查询成本。

您可以通过将 PostgreSQL 参数 cursor_tuple_fraction 设置为 1.0 来禁用此优化。

If you are using a cursor, PostgreSQL estimates that only 10% of the query result will be fetched quickly and prefers plans that return the first few rows quickly, at the expense of the total query cost.

You can disable this optimization by setting the PostgreSQL parameter cursor_tuple_fraction to 1.0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文