PG 向量化引擎--2

yzs87發表於2022-01-29

PG 向量化引擎 --2

向量化引擎是 OLAP 資料庫提升效能的有效技術。翻到 PostgreSQL 郵件列表有對向量化引擎的討論。這裡繼續進行整理,以作分析。

關於設計中的幾個問題

1 、在 vtype 中使用原生陣列而不是 Datum 陣列會更有效嗎?我認為針對 float4 int32 型別的操作,它將允許編譯器產生更加有效的程式碼

是的,我也在考慮掃描列存時,將列 batch 載入到連續的記憶體區域中。對於 Int32 ,此區域大小時 4*BATCHSIZE ,而對於 Int16 ,大小時 2*BATCHSIZE 。所以使用原生資料可以只做一個 memcpy 來填充 vtype batch

2 、為什麼 VectorTupleSlot 中包含元組的資料( batch )而不是向量( vtype 的陣列)?

首先, VectorTupleSlot tts_values 域儲存 vtype 的陣列,這樣做減少了程式碼的更改量,擯棄可以重用像 ExecProject 類似的函式。當然,我們也可以使用單獨的欄位來儲存 vtypes

其次, VectorTupleSlot 還包含堆元組資料。這屬於堆元組的變形。事實上,一個 batch 中包含的元組可能跨多個頁。因此我們需要 pin 住相關頁的陣列,而不僅僅是一個頁

3 、為什麼必須實現子集的 plan_tree_mutator 而不是使用 expression_tree_mutator?

我也想要替換 Plan 節點,例如 Agg->CustomScan( 使用 VectorAgg 實現 ) expression_tree_mutator 不能夠用於變異 plan node ,如 Agg ,對嗎?

4 、據我瞭解,您現在總是嘗試用自己定義的向量化 scan 來替代 SeqScan 。但只有當此掃描或聚合執行了 quals 才有意義。其他情況下, batch+unbatch 只會增加額外的開銷,不是嗎?

可能 heap 格式和 select i from t 沒有 qual projection aggregation 的查詢才會有額外的開銷。但是對於列存, VectorScan 可以直接讀 batch ,沒有額外的 batch 代價。列存是 OLAP 查詢更好的選擇。我們是否可以得出結論,對於 OLAP 查詢使用向量化引擎,對於 OLTP 查詢使用行引擎會更好。

5 、對於不能向量化的查詢捕獲並丟擲異常不是處理此類情況最安全和最有效的方法。在 plan_tree_mutator 中返回錯誤程式碼,並將此錯誤傳播到上層可能會更好嗎?

是的,至於效率,另一種方法是僅對某些 plan 節點進行向量化,而其他節點不向量化,透過在他們之間新增 batch/unbatch 節點來實現(這是你說的“在上層傳播此錯誤”?)。正如您所提到的,這可能會帶來額外的開銷,還有其他好的方法嗎?您說的最不安全是什麼意思? PG catch 接收 ERROR ,反饋給原始非向量化 plan

--hackers 中對 catching 和忽略 exception 進行了多次討論,不幸的是 PG PG_TRY/PG_CATCH 機制不是高階語言 C++ java 等機制的變種。它不會執行堆疊 unwind 。如果在丟擲錯誤之前獲取了一些資源( files locks memory 等),那麼這些資源不會回收。僅回滾事務才能釋放所有資源。實際上它發生在正常錯誤處理情況下。但如果捕獲並忽略異常,檢視繼續執行,那麼可能會導致更多問題。

可能在您情況下,這個不是問題,因為您確定錯誤發生在哪裡,他是由 plan_tree_mutator 丟擲的,並且看起來這個函式沒有獲得任何資源。但是在任何情況下 setjmp 開銷都遠高於對返回碼的顯式檢查。因此,檢查返回碼實際上不會增加一些明顯的開銷,除了透過新增額外的檢查使得程式碼複雜化。但是可以透過宏例如 MUTATE 來隱藏這些複雜度。

6 、你測試過不同 batch 大小嗎?我在 VOPS 中做了類似測試,發現大於 128 的大小並沒有帶來顯著的效能提升。你當前使用 batch 大小是 1024 ,它明顯大於一頁上元組數量。

好的,將對此進行一些實驗

7 、如何將向量化掃描和並行結合起來( 9.6 已支援)

目前還沒實現。但這個想法與非並行的想法相同。複製當前並行掃描並實現向量化 Gather ,保持介面都是 VectorTupleTableSlot 。我們基本思路是複用當前 PG 執行邏輯大部分程式碼,然後進行向量化,並逐步進行效能調優。

-- 並行掃描時在並行 worker 之間分散頁。為填充 VectorTupleSlot ,可能需要不止一頁(除非你決定僅在單頁中獲取元組)。因此應該以某種方式考慮並行查詢的具體請。還有用於並行查詢的特殊節點,所以如果我們想為向量化操作提供並行執行,我們還需要用自定義節點替換這個節點。

做的一些效能測試

Q1 的結果:

max_parallel_workers_per_gather

PG9_6, enable_vectorize_engine=off

PG9_6, enable_vectorize_engine=on

master (jit=on)

0

36

20

10

4

10

--

5

9.6 相比, PG13 OLAP 查詢中提供了顯著優勢。當然並不意味著新版本的 PG 不需要向量化執行器。無論如何,我認為向量化執行器至於與列存結合才有意義。

Konstantin Knizhnik 的測試

vectorize_engine 移植到 master 。花費的時間比預期要長: executor 程式碼中很多東西都發生了改變:

par.warkers

PG9_6
向量化=關閉

PG9_6
向量化=開啟


向量化=關閉
jit=開啟


向量化=關閉
jit=關閉


向量化=on
jit=ofn


向量化=on
jit=off

0

36

20

16

25.5

15

17.5

4

10

-

5

7

-

-

因此,它證明了 JIT 提供與向量化執行器計劃相同的加速理論(這這都消除了解釋開銷,但方式不同)。我仍然不確定我們是否需要向量化執行器:因為與當前的 JIT 版本相比,標準 heap 幾乎沒有任何改進。但無論如何,我們將使用列存 zedstore cstore 對其進行測試。

列存的比較

par.workers

PG9_6
vectorize=off

PG9_6
vectorize=on

master
vectorize=off
jit=on

master
vectorize=off
jit=off

master
vectorize=on
jit=on

master
vectorize=on
jit=off

zedstore vectorize=off
jit=on

zedstore vectorize=off
jit=off

zedstore vectorize=on
jit=on

zedstore vectorize=on
jit=off

0

36

20

16

25.5

15

17.5

18

26

14

16

4

10

-

5

7

-

-

5

7

-

-

差距很小。

原文


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31493717/viewspace-2854553/,如需轉載,請註明出處,否則將追究法律責任。

相關文章