4

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

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

4

3 回答 3

7

首先使用子查询或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)。

于 2013-02-20T15:30:41.743 回答
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$
于 2013-02-20T17:37:26.240 回答
1

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

但如果你想尝试一下,请查看“enable_seqscan”和其他设置,参见例如PostgreSQL 文档

于 2013-02-20T15:37:28.697 回答