問題
我有查詢,SELECT p.* FROM parties p INNER JOIN bib b ON p.id=b.id;.
在 Postgres 版本 9.2.24 上,此查詢需要 12 或 13 分鐘。這是EXPLAIN ANALYZE上述查詢的輸出:
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------
Hash Join (cost=156455.80..24854275.23 rows=4608791 width=46) (actual time=2516.474..407029.156 rows=4556073 loops=1)
Hash Cond: (p.id = b.pid)
-> Seq Scan on parties p (cost=0.00..22882138.64 rows=128697664 width=46) (actual time=371.099..220812.052 rows=133719944 loops=1)
-> Hash (cost=98845.91..98845.91 rows=4608791 width=4) (actual time=2141.741..2141.741 rows=4608467 loops=1)
Buckets: 524288 Batches: 1 Memory Usage: 162017kB
-> Seq Scan on bib b (cost=0.00..98845.91 rows=4608791 width=4) (actual time=21.570..1199.429 rows=4608467 loops=1)
Total runtime: 407293.833 ms
(7 rows)
在 Postgres 版本 10.17 上,此查詢大約需要3 小時。這是EXPLAIN ANALYZE上述查詢的輸出:
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------
Gather (cost=1000.57..12597544.56 rows=10945244 width=1038) (actual time=49.143..31536008.494 rows=10854924 loops=1)
Workers Planned: 5
Workers Launched: 5
-> Nested Loop (cost=0.57..11502020.16 rows=2189049 width=1038) (actual time=88.401..31499828.808 rows=1809154 loops=6)
-> Parallel Seq Scan on bib b (cost=0.00..147545.49 rows=2189049 width=4) (actual time=3.113..1830.876 rows=1824207 loops=6)
-> Index Scan using idx_parties_cmp on parties p (cost=0.57..5.18 rows=1 width=1038) (actual time=17.262..17.265 rows=1 loops=10945244)
Index Cond: (id = b.id)
Planning time: 114.828 ms
Execution time: 31536841.489 ms
(9 rows)
筆記
- 兩個資料庫有相似的資料
- 兩個資料庫具有相同的索引
- 兩個資料庫具有相同的配置
- 兩個資料庫都在相同數量的 ram 上運行 - 125 GB
- 9.2.24 資料庫具有更多交換空間(11 GB 與 10.17 上的 3 GB)
- 我已經運行
vacuumdb --all --analyze-in-stages在兩個
問題
為什么在 Postgres 10.17 中查詢花費的時間要長得多? 我意識到第二個查詢回傳了大約 600 萬行,但它需要 525 分鐘而不是 7 分鐘。600 萬的差異真的可以解釋 75 倍的性能下降嗎?
costPostgres 版本之間的測量值是否相同? 因為 10.17 上的查詢成本大約是9.2 版查詢成本的一半,但它需要大約 30 倍的時間。
uj5u.com熱心網友回復:
成本估算在 9.2 和 10 之間發生了變化,但不是根本性的(假設可配置的設定沒有發生根本性的變化——除非你告訴我們,否則我們無法知道)。
最大的區別(可能與您相關的那些)是查詢內并行化的引入,這當然需要更改成本模型。v10 認為總成本將減少 2 倍,但它也認為它將有 6 個行程專用于它,因此它認為總共將使用 3 倍以上的資源。它可能沒有從并行化中獲得任何好處(因為您的硬體不足),但它錯誤地認為它會。
請注意,在 v10 中 max_parallel_workers_per_gather 的默認設定是 2,但您顯然是在使用至少 5 的設定運行的。換句話說,設定您的服務器的人顯然不顧一切地向 PostgreSQL 撒謊說服務器的能力如何.
現在顯然這不是唯一的估計問題。如果我們說回傳兩倍的資料需要 75 倍的時間,并在并行化積分中將其原諒 6 倍,那仍然會導致錯誤的大約另一個 6 倍。但據我們所知,它也被取消了甚至在 9.2 中的數量。可能是 6 折估計誤差仍然使嵌套回圈看起來更昂貴,因此沒有選擇它。只有當該誤差與并行錯誤估計相結合時,組合誤差才會變得高到足以改變計劃。確定的方法是強制 9.2 使用嵌套回圈計劃,并查看它實際上慢了多少,以及它預期的成本有多少。當然,如果練習的目的是“我該如何解決這個問題”而不是“我該怪誰”,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/410444.html
標籤:
上一篇:添加連接以根據鍵顯示專案
