【问题标题】:Postgres Query Plan keeps changing - takes a query a minute to finish sometimes and never finishes sometimesPostgres 查询计划不断变化 - 有时需要一分钟才能完成查询,有时永远不会完成
【发布时间】:2016-06-22 17:26:16
【问题描述】:

我有大量的 SQL 查询。可能涉及 15-20 张桌子。 有 6 到 7 个子查询再次连接。 大多数情况下,此查询需要一分钟才能运行并返回 500 万条记录。

因此,即使这个查询写得不好,它也有可以在一分钟内完成的查询计划。我确保查询实际运行并且没有使用缓存结果。

有时,查询计划被抬高,然后就永远不会完成。我每天晚上对查询中涉及的表进行一次真空分析。 work_memory 当前设置为 200 MB。我也尝试将其增加到 2 GB。当 work_memory 为 2 GB 时,我还没有遇到过查询变得混乱的情况。但是当我减少它并运行查询时,它变得一团糟。现在,当我将它增加到 2 GB 时,查询仍然一团糟。是否与查询计划未使用新设置刷新有关?我在会话中尝试了放弃计划。

此时我只能想到work_mem和vacuum analyze。是否有其他因素会影响顺利运行的查询,该查询会在一分钟内返回结果而不返回任何内容?

如果您需要有关任何设置的更多详细信息,请告诉我?还是查询本身?我也可以粘贴计划...但是查询和计划太大而无法粘贴在这里..

【问题讨论】:

  • 范围表中的 15-20 个表:基因优化器将启动。要么增加 geqo_limit,要么将一些表引用放入 CTE。如果您已经有一些子查询,请将其中的一个或多个提升为 CTE。
  • 哎呀,名字是geqo_threshold。它的默认值为 12。将其设置得太高(20 可能太高了......)将导致计划者需要 大量时间 来评估所有计划。 (计划的数量基本上是 RTE 数量的指数)

标签: database postgresql database-administration sql-tuning


【解决方案1】:

如果范围表中的条目超过 geqo_treshold(通常为 12 个),遗传优化器将启动,通常会导致 随机 行为,如问题中所述。您可以通过以下方式解决此问题:

  • 增加geqo_limit
  • 将一些表引用移动到 CTE 中。如果您已经有一些子查询,请将其中的一个(或多个)提升为 CTE。在您的查询中识别适合compact CTE 的表集群是一种魔法(结果元组相对较少,对外部查询的关键引用也不多)。李>

将 geqo_treshold 设置得太高(20 可能太高了……)会导致规划者需要大量时间来评估所有计划。 (计划的数量基本上是 RTE 数量的指数增长)如果您预计您的查询需要几分钟来运行,那么几秒钟的计划时间可能不会造成任何伤害。

【讨论】:

  • 阅读了 GEQO 设置。我很确定这是我的问题。我的查询太长太复杂,无法生成详尽的搜索计划。基于 GECO 的启发式搜索并未产生最佳计划。我将稍微调整 geqo_effort 参数并将查询中的重复部分分解为 CTE
  • 但是您是否知道每次我的查询计划被弄乱时,对整个数据库的真空分析可以解决问题。 GEQO 是否能够在真空分析后做出更好的计划?
  • 这只是随机性&巧合&启发式,我不想知道。可能是您有增量键,甚至是统计数据中的错误计算...一旦 geqo 产生相关表的集群,使用该集群的变体可能会占上风。 (赢得进化)。我的建议:只需将查询的(实体子查询)部分拆分为 CTE。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-08
  • 1970-01-01
相关资源
最近更新 更多