【问题标题】:Change the execution plan of query in postgresql manually?手动更改postgresql中查询的执行计划?
【发布时间】:2013-02-05 14:07:00
【问题描述】:

是否可以在 postgresql 中手动更改执行计划的操作顺序?例如。如果我总是想在过滤之前进行排序操作(尽管它在 postgresql 的正常使用中没有意义),是否可以通过例如手动强制执行该操作改变运营的内部成本?

如果我实现自己的功能呢?是否可以让这样的函数始终在 sql 语句的最后执行?

【问题讨论】:

  • 您可以尝试使用 CTE(又名WITH 子句)来强制执行操作顺序。

标签: sql postgresql common-table-expression


【解决方案1】:

首先使用子查询或CTE 强制执行某些操作。喜欢:

SELECT *
FROM  (
   SELECT *
   FROM   tbl
   LIMIT  10
   ) x
ORDER  BY 1;

当然,您需要了解您在做什么。在示例中,我选择了 10 个 任意 行,然后按第一列对它们进行排序。
您可以连续使用多层子查询或多个 CTE。

与 CTE 相同的示例:

WITH x AS (
   SELECT *
   FROM   tbl
   LIMIT  10
   )
SELECT *
FROM   x
ORDER  BY 1;

对于简单查询,子查询通常更快,CTE 提供额外的功能(例如在不同查询级别的多个地方重用相同的 CTE)。

【讨论】:

  • 感谢您向我介绍 CTE,Erwin Brandstetter!多个 CTE 呢?他们是否按顺序执行?非常感谢您!
  • @Gracchus:不一定。仅当您引入功能依赖项(一个 CTE 引用另一个)时。外部查询中未引用的 CTE 可能根本不会被调用。 More ... 还有special rules for data-modifying CTEs ...
  • @Gracchus:您确实在我的第二个链接中看到,数据修改 CTE 是始终执行的,对吗?如果不需要,只有 SELECT 查询可以被优化掉。
  • 啊,谢谢你的澄清!我的眼睛/大脑专注于一个关键元素,怪胎,有时会放弃细节,哈哈。再次感谢 Erwin Brandstetter!
【解决方案2】:

还有更多方法——这里展示了一些方法,但还有第二种方法,如果你想在处理结束时移动函数调用,那么只需将 COST 设置为更高的值。自定义函数的默认值为 100,但您可以设置更高的值。

CREATE OR REPLACE FUNCTION public.test()
 RETURNS integer
 LANGUAGE plpgsql
 IMMUTABLE COST 1000 -- very expensive function
AS $function$
declare i int;
declare j int;
begin
  i := 1;
  while i < 10000 loop
    j := 1;
    while j < 1000 loop
      j := j + 1;
    end loop;
    i := i + 1;
  end loop;
  return i;
end;
$function$

【讨论】:

    【解决方案3】:

    如果没有 CTE(其他人已经解释过),您能做的最好的事情就是关闭某些类型的操作。这通常被认为是危险的,并且是不得已而为之的方法,因为它通常指向数据库中的错误(即缺少索引、没有足够的清理、分析采样过低)或 PostgreSQL 代码中的错误。

    但如果您想尝试一下,请查看“enable_seqscan”和其他设置,例如PostgreSQL documentation

    【讨论】:

    • 这真的用于调试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多