1. 程式人生 > 其它 >關於SQL語句轉DSL語句的一些實踐和思考(一)

關於SQL語句轉DSL語句的一些實踐和思考(一)

現在接觸的專案是公司的路由中臺,每天的資料量是億級別的,同時要記錄每一次請求的詳細資料

開始的時候這些記錄資料是存放到elasticsearch與DB2資料庫中各自儲存

當需要查詢某個路由資訊的詳情時從ES中獲取,速度非常快,當想獲取統計報表的時候從DB2中統計,本來是相安無事的,ES速度快,DB2是關係型資料庫,易於統計分析

但是因為公司要放棄DB2資料庫,所以做統計分析的SQL語句也就沒用了,需要從ES中獲取資料並統計分析

這個時候問題就出現了,較為複雜的SQL語句如何轉變為DSL語句

如何分組?如何關聯?如何子查詢

關於基本SQL如何轉變為DSL語句,大家可以參考這個網站http://www.atotoa.com/,同時還有一些開源框架,這裡我沒有使用,公司這邊純內網開發,找不到那種東西就沒用

,java端使用的是highlevelclient

目前這些轉變中已經做到了分組和聚合的對應,但是其中也有一些細節需要拿出來說一說

一:group by和aggs的區別

SQL語句分組查出來的資料仍然是扁平的資料,最終還是能得到一個List<T> ,但是DSL通過Aggs聚合得到的資料是有深度的,一層套一層,如果想獲取到SQL那種資料結構,理論上來說聚幾次就需要幾層迴圈一層層的取.

在公司專案改造中,為了取出資料使用了7層迴圈去取資料

二:也許有的sql還不止7層,使用7層妖塔似乎有點滲人,其他方法有沒有呢

確實可以將聚合拆分,可以每次aggs一次,但是在拿到這些資料時,需要對聚合7次獲取的資料設計一個演算法,通過這種方式獲取到資料有問題,最終放棄了(其實這是一個很好的思路,7次聚合帶來的壓力如果分成7個單一聚合,ES服務會非常安全)

三:聚合7次帶來的伺服器壓力

公司每日的資料都存入一個新的index,測試庫2000W資料 將近60G 大小,而生產庫每天億級資料,這麼大量的資料進行7次聚合,最終會直接讓伺服器崩潰

多次測試發現多次聚合都導致了測試ES崩潰,雖然生產伺服器更強大,但是這樣肯定不行

四:使用query_match代替聚合

如果要進行兩次聚合,比如下面的語句

實際上也可以使用

將聚合條件轉變為query條件,讓聚合次數降低,單次查詢數量級下降

比如在我的生產庫中有2E跳資料,我使用的query欄位有1000個值,那麼每次聚合的資料就是2E/1000=20W

把一次查詢ES 2E的資料量變為查詢1000次ES每次查20W的資料量

java程式碼雖然複雜了點,但是完全值得