2011-10-25 29 views
5

我有一個查詢,運行很慢(~5分鐘),當我用默認的enable_nestloop = true和enable_nestloop = false(〜10秒)運行它時。Postgresql - 使用enable_nestloop = false,查詢運行速度更快。爲什麼規劃師不能做正確的事情?

解釋爲這兩種情況下分析結果:

機器A nestloop =真 - http://explain.depesz.com/s/nkj0(〜5分鐘) 機器A nestloop =假 - http://explain.depesz.com/s/wBM(〜10秒)

在一個不同的速度稍慢機,複製數據庫並保留默認的enable_nestloop = true需要20秒。

機器B nestloop =真 - (〜20secs)

上述所有我的情況下,確保我沒有運行查詢之前的分析一下。沒有其他查詢並行運行。

兩臺機器都運行Postgres 8.4。機器A運行Ubuntu 10.04 32位,而機器B運行Ubuntu 8.04 32位。

實際查詢可在此處獲得。由於數據庫主要用於事務處理,因此它是具有多個聯接的報告查詢。

  1. 沒有求助於投入像物化視圖我能做些什麼,使規劃師做我設置ENABLE_NESTLOOP =假的實現?

  2. 從我所做的研究看來,計劃者選擇看似不理想的查詢的原因是由於估計行和實際行之間的巨大差異。我怎樣才能讓這個數字更接近?

  3. 如果我應該重寫查詢,我應該改變什麼?

  4. 爲什麼規劃師似乎在爲機器B做正確的事情。我應該在兩臺機器中進行比較?

+0

上述問題的鏈接必須刪除 - 查詢 - http://pastie.org/2754424 – Mohan

+0

解釋分析機B - http://explain.depesz.com/s/dYO – Mohan

回答

2

原來重寫查詢是最好的修復方法。該查詢的寫作方式嚴重依賴於左連接,並且有許多連接。我將它展平並通過使用我對查詢加入的表中數據連接性質的瞭解來減少左連接。我認爲經驗法則是,如果計劃者出現真正糟糕的估計,那麼編寫查詢可能會有更好的方式。

2

如果查詢計劃人員選擇次優查詢計劃,那麼可能會有不完整或具有誤導性的信息來處理。

有關服務器調整,請參閱此PostgreSQL Wiki page。特別要注意的章節random_page_costdefault_statistics_target
另請閱讀Statistics Used by the PlannerPlanner Cost Constants手冊中的相應章節。

更具體地說,它可能有助於增加statistics target以下欄目:

ALTER TABLE postgres.products ALTER COLUMN id SET STATISTICS 1000; 
ALTER TABLE postgres.sales_orders ALTER COLUMN retailer_id SET STATISTICS 1000; 
ALTER TABLE postgres.sales_orders ALTER COLUMN company_id SET STATISTICS 1000; 

ALTER TABLE goods_return_notes ALTER COLUMN retailer_id SET STATISTICS 1000; 
ALTER TABLE goods_return_notes ALTER COLUMN company_id SET STATISTICS 1000; 

ALTER TABLE retailer_category_leaf_nodes ALTER COLUMN tree_left SET STATISTICS 1000; 
ALTER TABLE channels ALTER COLUMN principal_id SET STATISTICS 1000; 

這些參與導致估計和實際行之間的

巨大差異的過濾器。

還有更多。檢查刨牀偏離預估的每一列。缺省值僅爲100.對於具有>> 1000行的表,只有意義。嘗試設置。之後在表格上運行ANALYZE以使更改生效。

它也可能有助於在postgres(sales_orders.retailer_id) WHERE retailer_id IS NOT NULL上創建一個部分索引(具體取決於常見的NULL值)。


,可以幫助你的另一件事是升級 9.1的最新版本。這方面已經有了許多重大改進。

+0

我欣賞事實athe配置可以有所作爲。但機器A和機器B之間的配置完全相同。你知道我應該看的任何特定的pg_stats類型參數嗎? – Mohan

+0

@莫漢:我用更具體的提示修改了我的答案。 –

+0

謝謝歐文。我們嘗試升級到9.1以及將random_page_cost設置爲較低的值 - 無濟於事。我會嘗試你的其他建議。 – Mohan

0

對於具有相同PostgreSQL的兩臺服務器上的相同數據和相同查詢,通常只有一個原因。這是不同的配置 - 主要是work_mem的價值。散列連接通常更快,但需要大量可用內存。

2

這可能是有用的閱讀: PostgreSQL tutorial about explicit JOINs

查詢計劃程序嘗試分析JOIN順序以查找JOINing的最佳順序。

我看到您的查詢至少有15個JOIN。可能的JOIN訂單的數量上升爲階乘(n!)。因此,如果查詢規劃器有15個JOIN,那麼嘗試查找最佳JOIN順序是不合理的 - 它必須查看15個JOIN! = 1307674368000不同的計劃。

所以它使用Genetic Query Optimizer。請參閱Query Planning: Genetic Query Optimizer parameters。參數「geqo_threshold」確定查詢計劃器使用Genetic Query Optimizer時必須存在多少個JOIN。

這樣PostgreSQL計劃程序只查看可能變體的一小部分,並嘗試找到最好的一個(隨機)。所以每次運行ANALYZE時,都可能會提出更好的計劃。

我認爲,一般來說,如果你有很多表加入,你最好像你做的那樣做:重寫查詢以獲得最佳JOIN順序。

相關問題