2013-02-20 74 views
4

是否可以在postgresql中手動更改執行計劃的操作順序?例如。如果我總是希望在過濾之前進行排序操作(儘管在正常使用postgresql時沒有意義),是否可以通過例如手動強制執行該操作。改變一項行動的內部成本?手動更改postgresql中查詢的執行計劃?

如果我實現自己的功能呢?是否有可能在sql語句的最後執行這樣的函數?

+0

您可以嘗試使用CTE(又名'WITH'子句)來強制執行操作順序。 – 2013-02-20 14:45:39

回答

2

有更多的方式 - 一些在這裏顯示,不過也有第二種方法,如果你想繼續前進處理結束函數調用,那麼就設置成本高一些價值。自定義函數的默認值是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$ 
6

使用子查詢或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在多個地方)。

+0

謝謝你向我介紹CTE,Erwin Brandstetter!怎麼樣多個CTE?他們是否按順序執行?提前感謝你! – 2014-07-16 01:49:39

+1

@Gracchus:不一定。只有當你引入函數依賴時(一個CTE引用另一個)。在外部查詢中未引用的CTE可能根本不會被調用。 [更多...](http://dba.stackexchange.com/questions/69648/postgresql-seems-to-ignore-raise-exception-in-a-cte/69650#69650)還有[特別規則數據修改CTE ...](http://stackoverflow.com/questions/15809463/postgresql-using-foreign-keys-delete-parent-if-its-not-referenced-by-any-othe/15810159#15810159 ) – 2014-07-16 01:59:06

+1

@Gracchus:您在我的第二個鏈接中看到數據修改CTE總是被執行,對嗎?如果不需要,只有'SELECT'查詢可以被優化掉。 – 2014-07-16 03:28:57

1

關於您可以不用做熱膨脹係數(其中其他人解釋)最好是關閉某些類型的操作。這通常被認爲是危險的,並且是一種最後的方法,因爲它通常指向數據庫中的錯誤(即缺少索引,不夠清空,分析採樣太少)或PostgreSQL代碼。

但是,如果你想嘗試一下,擡頭「ENABLE_SEQSCAN」等設置,例如見PostgreSQL documentation

+2

這真是*只*用於調試。 – 2013-02-20 16:40:01