用http服務的方式集成learned cardinality estimate方法進 Postgresql 。本文的重點在於PG的修改。記錄一下我的修改思路。整體流程為PG作為http客戶端,向基數估計服務端發送http請求。內容為需要基數估計的sql語句。基數估計服務端返回該語句的selecti... ...
代碼地址:postgresql-13.1-ml: Integration of CardEst Methods into PostgreSQL by HTTP Server (github.com)
當前進度:可以支持單表查詢的基數估計模塊的替換。至於多表join的基數估計模塊替換還在開發中
註意:本文的重點在於PG的修改。記錄一下我的修改思路。
整體流程
PG作為http客戶端,向基數估計服務端發送http請求。內容為需要基數估計的sql語句。
基數估計服務端返回該語句的selectivity。
PG收到該查詢的selectivity後乘以當前表的大小,即得到rows
PG原版基數估計調用邏輯
修改源碼
主要修改代碼costsize.c
單表修改set_baserel_size_estimates函數
修改邏輯
其中get_expr函數的邏輯可參考print.c文件中print_expr函數
多表修改set_joinrel_size_estimates函數
待續
添加第三方庫
該項目需要其它兩個第三方庫
- C語言的HTTP服務的client端的庫,參考項目:linux下socket(C)構造HTTP客戶端
- C語言解析json格式的庫,參考項目:cJSON
將第三方庫的頭文件和實現文件加入到PG中:
- 把http.h 添加到 /src/include/utils/下
- costsize.c 添加 #include "utils/http.h”
- 把cJSON.h 添加到 /src/include/utils/下
- 把cJSON.c 添加到 /src/backend/utils/adt/下
- cJSON.c 把#include "cJSON.h”修改成#include "utils/cJSON.h”
- 在/src/backend/utils/adt/Makefile添加 cJSON.o \
- costsize.c 添加 #include "utils/cJSON.h”
效果
單表查詢的效果
測試數據集:imdb.title
PG原版計劃 VS learned方法的計劃
最優計劃
可以看到learned方法基數估計更準確,產生的執行計劃與基數估計幾乎正常產生的計劃一致。而PG原版的基數估計由於準確度太低,導致產生了次優的執行計劃。
雖然learned方法的速度沒有PG原版快,但產生的計劃更優,導致節省了執行時間,所以整體時間更優。
多表查詢的效果
待續
待完善
- 多表查詢的基數估計部分還在開發中
- 當前版本只適用於實驗環境。尚未對不支持的查詢進行過濾。
參考資料
- End-to-End-CardEst-Benchmark
- VLDBSS2022實驗
- PostgreSQL 在內核增加一個配置參數
- linux下socket(C)構造HTTP客戶端
- cJSON使用詳細教程 | 一個輕量級C語言JSON解析器
- cJSON