PostgreSQL 查詢成本模型

發表於2017-12-21

摘要:PostgreSQL是一個自由的物件-關聯式資料庫伺服器(資料庫管理系統),被業界譽為“最先進的開源資料庫”,本文作者以程式碼例項說明了如何計算和評估PostgreSQL查詢成本,以下是譯文。

資料庫查詢速度如果太慢會從很多方面損害機構,比如可能會損害一些優秀應用程式的聲譽,因為資料庫查詢速度過慢,造成後臺處理速度慢得令人痛苦,並大幅增加基礎設施的成本。作為一名經驗豐富的Web開發人員,瞭解資料層的優化策略是絕對必要的。

這裡寫圖片描述

在本文中,我們將探討PostgreSQL的成本模型,如何瞭解explain命令(關於explain命令可參見這篇文章)的輸出,最重要的是如何利用這些模型資料來提高應用程式的吞吐量。

使用PostgreSQL Explain 命令

在應用程式中部署一個新的查詢語句之前,最好通過PostgreSQL中的 explain中的命令來執行它,以評估新查詢對應用系統效能的影響。

以一個示例資料庫表開始,來說明explain命令的用法。這個表存有一百萬條資料記錄。

假設需要用一個給定的id來查詢一個使用者名稱,但是在部署新的查詢程式碼之前,要評估這個查詢操作的成本。執行一個explain語句來做相關查詢:

在上面的例子中有很多的輸出,但是可以得到它的要點。為了執行這個查詢,PostgreSQL計劃啟動兩個並行的工作程式(workers)。每個工作程式將在表上進行順序掃描,最後,收集器合併來自兩個工作程式的結果。

在本文中,重點介紹上面輸出的cost以及PostgreSQL如何計算它。

為了簡化成本探索,執行上面的查詢,但限制可並行的工作程式數量為0。

這有點簡單。在只有單CPU核心的情況下,評估成本是17906

成本值背後的數學

在PostgreSQL中,成本或懲罰點大多是一個抽象的概念。PostgreSQL可以執行查詢的方式很多,而PostgreSQL總是選擇最低成本值的執行規劃。

計算成本,PostgreSQL首先檢視錶的位元組數大小。接下來看看使用者表的大小。

PostgreSQL會為每個要依次讀取的塊新增成本點。如果知道每個塊都包含了8kb,那麼就可以計算從表中讀取的順序塊的成本值。

現在,已經知道塊的數量,找出PostgreSQL為每個塊讀取分配多少個成本點。

換句話說,PostgreSQL為每個塊分配一個成本點。這就需要 5406個成本點從表中讀取資料。

從磁碟讀取值並不是PostgreSQL需要做的。它必須將這些值傳送給CPU並應用一個WHERE子句過濾。對於這個計算來說,如下的兩個值非常有趣。

現在,用所有的值來計算在explain 語句中得到的值。

索引和PostgreSQL成本模型

索引在資料庫工程師的生活中很可能仍然是最重要的話題。新增索引是否可以降低SELECT語句的成本呢?通過下面的例子來找出答案。

首先,在users表中新增一個索引:

觀察一下新索引的查詢規劃。

成本函式顯著下降。索引掃描的計算比順序掃描的計算要複雜一些。它由兩個階段組成。

PostgreSQL會考慮random_page_costcpu_index_tuple_cost 變數,並返回一個基於索引樹的高度的值。

對於實際的計算,請考慮閱讀成本指數計算器的原始碼。

工作程式的成本

PostgreSQL可以啟動並行的工作程式(worker)來執行查詢。但是,開啟一個新的工作程式,效能會受到影響。

為了計算使用並行工作程式的成本,PostgreSQL使用 parallel_tuple_cost這個命令,它定義了從一個工作程式傳送元組到另一個工作程式的成本,parallel_setup_cost命令意味著啟動一個新的工作程式(worker)的成本,以下是查詢示例。

相關文章