2012-04-13 24 views
34

我有一個表/ 450萬行。沒有主鍵。該表有一列p_id,類型爲整數。本欄使用btree方法有一個索引idx_mytable_p_id。我做的:瞭解postgres解釋瓦特/位圖堆/索引掃描

SELECT * FROM mytable WHERE p_id = 123456; 

我運行這樣的一個解釋,看到下面的輸出:

Bitmap Heap Scan on mytable (cost=12.04..1632.35 rows=425 width=321) 
    Recheck Cond: (p_id = 543094) 
    -> Bitmap Index Scan on idx_mytable_p_id (cost=0.00..11.93 rows=425 width=0) 
     Index Cond: (p_id = 543094) 

問題:

  • 這是爲什麼查詢做了一堆掃描,然後一個位圖索引掃描?
  • 爲什麼檢查425行?爲什麼操作321的寬度?
  • 12.04..1632.35和0.00..11.93告訴我的費用是多少?

記錄中有773行,其中p_id的值爲123456.在mytable上有38列。

謝謝!

回答

52

這是爲什麼

這本手冊中的所有記錄查詢做堆掃描,然後進行位圖索引掃描?

這不是,確切地說。 EXPLAIN輸出顯示了執行節點的結構,其中「高」級(不會縮進)的行從下面的節點拉行。所以當位圖堆掃描節點去拉第一行時,位圖索引掃描將運行以確定要使用的一組行,並將第一行的信息傳遞給堆掃描。索引掃描通過索引來確定哪些行需要讀取,堆掃描實際上讀取它們。這個想法是,通過從頭到尾讀取堆而不是按索引順序讀取堆,它會減少隨機訪問 - 當加載頁面時,將讀取給定頁面中的所有匹配行,並且可以讀取足夠的頁面以便使用更便宜的順序訪問,而不是在整個磁盤上來回查找。

爲什麼檢查425行?

不是。你運行EXPLAIN,它只是顯示你的估計和選定的計劃,它根本不檢查行。與運行EXPLAIN ANALYSE相比,這使得EXPLAIN的值相當有限,實際上運行了查詢並顯示了估計值和實際的數字。

爲什麼操作321的寬度?

顯然這是mytable中元組的大小,以字節爲單位。

12.04..1632.35和0.00..11.93告訴我的費用是多少?

第一個數字是從該節點返回第一行的開銷;第二個數字是返回該節點的所有行的開銷。請記住,這些是估計值。該單位是一個抽象成本單位。絕對數字毫無意義;計劃中最重要的是哪個計劃成本最低。如果您使用的是遊標,則第一個數字很重要;否則它通常是第二個數字。 (我認爲它內插了一個LIMIT子句)。

通常需要調整可配置的成本因素(例如random_page_costcpu_tuple_cost),以精確地模擬環境中的成本。如果沒有這種調整,相對成本可能與相應的運行時間不匹配,因此可能會選擇不太理想的計劃。

+1

內部操作的總成本將始終包含在外部操作的啓動成本中。 – vyegorov 2012-04-13 20:08:43

+0

@vyegorov是正確的,對於來自EXPLAIN ANALYZE的**實際**數據,您應該明白節點所花費的總時間除以** loops **以顯示每次迭代的時間。正如您所期望的那樣,這是包含在封閉節點中的節點的總時間。 – kgrittn 2012-04-13 20:24:45

13

re 1)執行計劃必須從最內層的節點讀到最外層的節點。因此,它首先執行索引掃描(查找行)並訪問實際表以返回發現索引掃描的行

re 2)計劃中顯示的行數僅僅是基於統計信息的估計因此425與773聽起來相當合理。如果你想看到真正數字,使用explain analyze

重3)成本圖中的第一個號碼並初始化規劃者的步驟「啓動」成本,第二個成本是這一步的總成本。 http://www.postgresql.org/docs/current/static/using-explain.html

你可能想通過在PostgreSQL的維基這些鏈接,以及:

PostgreSQL EXPLAIN
Using Explain