2014-07-14 47 views
2

我有2個數據庫運行在同一臺服務器上。 兩者都是具有相同結構但數據量不同的開發數據庫。 在Linux上運行Postgres 9.2(Centos/Redhat)Postgres解釋計劃是不同的

我在每個數據庫上運行以下SQL,但在性能上獲得了非常不同的結果。

注意: write_history表結構在每個DB中是相同的,並且具有相同的索引/約束。

這裏是SQL:

explain analyze SELECT * FROM write_history WHERE fk_device_rw_id = 
'd2c969b8-2609-11e3-80ca-0750cff1e96c' AND fk_write_history_status_id 
= 5 ORDER BY update_time DESC LIMIT 1 ; 

而且解釋計劃每個DB:

DB1 - PreProd

Limit (cost=57902.39..57902.39 rows=1 width=103) (actual 
time=0.056..0.056 rows=0 loops=1)' -> Sort 
(cost=57902.39..57908.69 rows=2520 width=103) (actual 
time=0.053..0.053 rows=0 loops=1)' 
     Sort Key: update_time' 
     Sort Method: quicksort Memory: 25kB' 
     -> Bitmap Heap Scan on write_history (cost=554.04..57889.79 rows=2520 width=103) (actual time=0.033..0.033 rows=0 loops=1)' 
       Recheck Cond: (fk_device_rw_id = 'd2c969b8-2609-11e3-80ca-0750cff1e96c'::uuid)' 
       Filter: (fk_write_history_status_id = 5)' 
       -> Bitmap Index Scan on idx_write_history_fk_device_rw_id (cost=0.00..553.41 rows=24034 
width=0) (actual time=0.028..0.028 rows=0 loops=1)' 
        Index Cond: (fk_device_rw_id = 'd2c969b8-2609-11e3-80ca-0750cff1e96c'::uuid)' Total runtime: 0.112 ms' 

DB2 - QA

Limit (cost=50865.41..50865.41 rows=1 width=108) (actual 
time=545.521..545.523 rows=1 loops=1)' -> Sort 
(cost=50865.41..50916.62 rows=20484 width=108) (actual 
time=545.518..545.518 rows=1 loops=1)' 
     Sort Key: update_time' 
     Sort Method: top-N heapsort Memory: 25kB' 
     -> Bitmap Heap Scan on write_history (cost=1431.31..50762.99 rows=20484 width=108) (actual time=21.931..524.034 rows=22034 
loops=1)' 
       Recheck Cond: (fk_device_rw_id = 'd2cd81a6-2609-11e3-b574-47328bfa4c38'::uuid)' 
       Rows Removed by Index Recheck: 1401986' 
       Filter: (fk_write_history_status_id = 5)' 
       Rows Removed by Filter: 40161' 
       -> Bitmap Index Scan on idx_write_history_fk_device_rw_id (cost=0.00..1426.19 rows=62074 
width=0) (actual time=19.167..19.167 rows=62195 loops=1)' 
        Index Cond: (fk_device_rw_id = 'd2cd81a6-2609-11e3-b574-47328bfa4c38'::uuid)' Total runtime: 545.588 ms' 

那麼幾個問題:

  1. 之間有什麼區別 「排序方法:快速排序內存:25KB」 和 「排序方法:前N個堆排序內存:25KB」?

  2. 什麼可能導致總運行時間如此不同?

錶行計數:

DB1:write_history行數:5863565

DB2:write_history行數:2670888

請讓我知道,如果需要進一步的資料。 感謝您的幫助。

+0

你確定你每個都運行相同版本的PostgreSQL嗎? –

+0

你是否在兩個實例上有相同的內存配置? –

+0

_2運行在同一臺服務器上的數據庫_您的意思是相同的機器或相同的Postgresql服務器實例? –

回答

1

top-N排序意味着它正在排序以支持ORDER BY ... LIMIT N,並且一旦它可以顯示該元組不能在最上面的N.在排序過程中決定切換到前N排序。由於該類型具有零輸入元組,因此從未決定切換到它。所以報告方法的差異是一種效應,而不是原因;對這種情況並不重要。

我想你,關鍵是位圖堆掃描:

(actual time=0.033..0.033 rows=0 loops=1) 

(actual time=21.931..524.034 rows=22034 loops=1) 

較小的數據庫有很多符合您的標準,其行,所以有很多工作要做。

而且,做複查工作的需要量:

Rows Removed by Index Recheck: 1401986 

建議你work_mem設置爲work_mem的很小的值,所以你的位圖溢出它。

+0

非常感謝這個建議。我將work_mem從默認的1MB增加到了4MB。針對DB2中的表的查詢從36秒降至8秒。現在更易於管理。 – iamtheoracle

0

1)兩種不同的排序算法。

http://en.wikipedia.org/wiki/Quicksort

http://en.wikipedia.org/wiki/Heapsort

2)被分類會改變判定數據的音量。

從數據庫理論的記憶;由於掃描數據的順序,QuickSort在大量數據上執行得非常糟糕。如果排序需要將緩存緩存到磁盤,那就特別糟糕。堆排序比快速排序有更好的最壞情況。查詢計劃員知道這一點,並相應地更改計劃。

正在排序的行數是8倍大。要非常小心地注意預計要選擇的行數以及表中的行數。查詢規劃器使用數據的直方圖來更好地瞭解將要選擇的內容,而不僅僅是表中的行數。在DB1中是2。5K,在DB2中它是20K

您可以通過檢查結果集合是否與估計值中的計數匹配來檢查這些估計值是否正確。如果不是,那麼考慮執行ANALYZE

+0

謝謝你的回覆。欣賞信息。 – iamtheoracle