四、Doris物化視圖


使用場景: 

   在實際的業務場景中,通常存在兩種場景並存的分析需求:對固定維度的聚合分析對原始明細數據任意維度的分析

   例如,在銷售場景中,每條訂單數據包含這幾個維度信息(item_id, sold_time, customer_id, price)。在這種場景下,有兩種分析需求並存:

  • 業務方需要獲取某個商品在某天的銷售額是多少,那么僅需要在維度(item_id, sold_time)維度上對 price 進行聚合即可。
  • 分析某個人在某天對某個商品的購買明細數據。

在現有的 DorisDB 數據模型中:

  • 如果僅建立一個聚合模型的表,比如(item_id, sold_time, customer_id, sum(price))。由於聚合損失了數據的部分信息,無法滿足用戶對明細數據的分析需求。
  • 如果僅建立一個 Duplicate 模型,雖可以滿足任意維度的分析需求,但由於不支持 Rollup, 分析性能不佳,無法快速完成分析。
  • 如果同時建立一個聚合模型和一個 Duplicate 模型,雖可以滿足性能和任意維度分析,但兩表之間本身無關聯,需要業務方自行選擇分析表。不靈活也不易用。

MVs使用 


   物化視圖的出現主要是為了滿足用戶,既能對原始明細數據的任意維度分析,也能快速的對固定維度進行分析查詢的需求。

從定義上來說,MVs就是包含了查詢結果的數據庫對象,可能是對遠程數據的本地Copy;也可能是聚合后的結果。說白了,就是預先存儲查詢結果的一種數據庫對象。

在Doris中的物化視圖,就是查詢結果預先存儲起來的特殊的表。它的優勢在於:

  • 對於那些經常重復使用相同的子查詢結果的查詢性能大幅提升
  • Doris自動更新物化視圖的數據,保證Base 表和物化視圖表的數據一致性。無需額外的維護成本

說明注意:

  • 物化視圖的創建當前為異步操作。創建物化視圖的語法會立即返回結果,但物化視圖的生成操作可能仍在運行。
  • base表中的分區列,必須存在於創建物化視圖的group by聚合列中
  • 目前只支持對單表進行構建物化視圖,不支持多表JOIN ?
  • 聚合類型表(Aggregation),不支持對key列執行聚合算子操作,僅支持對value列進行聚合,且聚合算子類型不能改變。
  • 物化視圖中至少包含一個KEY列
  • 不支持指定物化視圖查詢 ?

 

創建物化視圖 


 

首先你需要有一個Base表,基於這個Base表的數據提交一個創建物化視圖的任務,任務中定義好物化視圖如何構建。 然后Doris就會異步的執行創建物化視圖的任務了。

如上圖以一個銷售記錄表為例:比如我們有一張銷售記錄明細表,存儲了每個銷售記錄的id,銷售員,售賣時間,和金額。 提交完創建物化視圖的任務后,Doris就會異步在后台生成物化視圖的數據,構建物化視圖。在構建期間,用戶依然可以正常的查詢和導入新的數據。創建任務會自動處理當前的存量數據和所有新到達的增量數據,從而保持和Base表的數據一致性。 用戶無需擔心一致性問題 。  

Flag :

  • 如上圖:創建表時不指定模型類型時,默認的是按什么類型的模型創建?
  • 物化視圖支持增量更新,但明細的訂單存在多次更新的場景,所以應該建立單一主鍵模型,搞不定聚合數據的正確性?

 

查詢  


 物化視圖創建完成后,用戶的查詢會根據規則自動匹配到最優的物化視圖

 

如上圖:有一張銷售記錄明細表,並且在這個明細表上創建了三張物化視圖。一個存儲了不同時間不同銷售員的售賣量,一個存儲了不同時間不同門店的銷售量,以及每個銷售員的總銷售量。 當查詢7月19日各個銷售員都買了多少錢時,我們 可以匹配mv_1物化視圖, 直接對mv_1的數據進行查詢。

 

自動匹配過程 


  

自動匹配的過程分為兩個步驟:

  • 對候選集合進行一個過濾。只要是查詢的結果能從物化視圖數據計算(取部分行,部分列,或部分行列的聚合)出都可以留在候選集中,過濾完成后候選集合大小 >= 1
  • 從候選集合中根據聚合程度,索引等條件選出一個最優的也就是查詢花費最少物化視圖。

 

過濾候選集執行過程 


 

候選集過濾目前分為4層,每一層過濾后去除不滿足條件的物化視圖。(例如: 查詢7月19日各個銷售員都買了多少錢為例)

  • 首先一開始候選集中包括所有的物化視圖以及Base表共4個。
  • 第一層 過濾先判斷查詢Where中的謂詞涉及到的數據是否能從物化視圖中得到,也就是銷售時間列是否在表中存在。由於第三個物化視圖中根本不存在銷售時間列。所以在這一層過濾中,mv_3就被淘汰了。
  • 第二層是過濾查詢的分組列是否為候選集的分組列的子集,也就是 銷售員id 是否為表中分組列的子集。由於第二個物化視圖中的分組列並不涉及 銷售員id 。所以在這一層過濾中,mv_2也被淘汰了。
  • 第三層 過濾是看查詢的聚合列是否為候選集中聚合列的子集,也就是對銷售額求和是否能從候選集的表中聚合得出。這里Base表和物化視圖表均滿足標准。
  • 最后一層 是過濾看查詢需要的列是否存在於候選集合的列中。由於候選集合中的表均滿足標准,所以最終候選集合中的表為 銷售明細表 ,以及 mv_1 這兩張。

 

選擇最優 


 候選集過濾完后輸出一個集合,這個集合中的所有表都能滿足查詢的需求,但每張表的查詢效率都不同。

這時候就需要在這個集合根據前綴索引是否能匹配到,以及聚合程度的高低來選出一個最優的物化視圖。

例如: 從 表結構中可以看出,Base表的銷售日期列是一個非排序列,而物化視圖表的日期是一個排序列,同時聚合程度上mv_1表明顯比Base表高,所以最后選擇出mv_1作為該查詢的最優匹配。  

 

查詢改寫 


 最后再根據選擇出的最優解,改寫查詢

 

 例如: 剛才的查詢選中mv_1后,將查詢改寫為從mv_1中讀取數據,過濾出日志為7月19日的mv_1中的數據然后返回即可。 

 

 特殊改寫 


 有些情況下的查詢改寫還會涉及到查詢中的聚合函數的改寫。 比如業務方經常會用到Count、Distinct對PV、UV進行計算。

 

例如上圖: 廣告點 擊明細記錄表中存放 哪個用戶點擊了什么廣告,從什么渠道點擊的,以及點擊的時間。 並且在這個Base表基礎上構建了一個物化視圖表,存儲了不同廣告不同渠道的用戶Bitmap值。
由於bitmap_union這種聚合方式本身會對相同的用戶 user_id 進行一個去重聚合。當用戶查詢廣告在Web端的UV的時候,就可以匹配到這個物化視圖。 匹配到這個物化視圖表后就需要對查詢進行改寫,將之前的對用戶id求 count(distinct) 改為對物化視圖中bitmap_union列求count。
所以最后查詢取物化視圖的第一和第三行求B itmap聚合中有幾個值。

 

物化視圖聚合函數 


 

 

未包含及部分函數解釋 

  • PERCENTILE_APPROX: 統計學中常用的分位數函數
  • HLL_UNION: 適用於快速進行非精確去重計算。對明細數據使用HLL_UNION聚合,需要先調用hll_hash函數,對原數據進行轉換 

 

查看物化視圖:

1、查看該database下的所有物化視圖

  • SHOW MATERIALIZED VIEW [IN|FROM db_name]

 2、查看指定物化視圖的表結構

  • DESC table_name all

3、查看物化視圖處理進度

  • SHOW ALTER MATERIALIZED VIEW FROM db_name

4、取消正在創建的物化視圖

  • CANCEL ALTER MATERIALIZED VIEW FROM db_name.table_name

5、如何確定查詢命中了哪個物化視圖 

 

 

 

參考資料



免責聲明!

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



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