關於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代碼雖然復雜了點,但是完全值得

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM