Log Service提供物化視圖功能,對目標SQL自動提取出子視圖(彙總、過濾、投影等)進行持久化,並在後續執行SQL分析時自動進行查詢改寫,從而顯著加速超大規模資料的分析效能。
背景介紹
為什麼要使用物化視圖
Log Service支援通過SQL對資料進行即時分析,即每次SQL執行,都是對選擇的時間範圍內的全量資料進行計算分析。在大規模資料量下,普通執行模式可能會遇到結果不精確、執行逾時、並發超限等問題。使用高效能完全精確查詢與分析(SQL獨享版)可以大幅提高計算能力,但支撐的資料規模仍然是有上限的,而且大規模資料下的執行時間也會比較長。因此對於超大規模資料,且對SQL執行時間有要求的情況下,比如Dashboard報表情境,我們可以通過建立物化視圖的方式,對報表中SQL 的子語句進行增量預計算並持久化中間結果。在後續重新整理報表的時候,就可以自動利用已經計算好的中間結果資料,從而大幅提升執行效能。
工作原理
原始日誌庫:原始日誌資料的LogStore(物化視圖不會對原始日誌庫產生任何影響)。
物化庫:建立物化視圖後,會自動建立一個對應的物化庫,用於儲存物化視圖的結果資料。
物化是按照寫入資料流式處理的,即使未經處理資料在日誌時間上存在亂序,定時物化的結果也不會存在重複或者遺漏。
後台定時計算:後台會針對輸入的SQL,自動提取出需要物化的模式,並定時對原始LogStore的資料,計算物化的中間結果。
使用者建立物化視圖的時候,只需要提供想要加速的SQL,無需自己考慮物化細節。
透明改寫:在執行一個任意的SQL查詢時,Log Service的執行引擎會對SQL的結構進行智能分析,自動匹配相應的物化視圖並進行透明改寫。
使用SQL的時候,只需要直接查詢原始LogStore。Log Service的計算引擎會自動匹配物化視圖並進行智能改寫,無需關心具體改寫過程。
保證最新資料可見度:Log Service的計算引擎會智能地處理查詢請求,對於已物化的資料範圍,直接從物化視圖中讀取;對於尚未物化的最新資料,則從原始日誌庫中即時讀取並計算,最終將兩部分結果自動合并,返回完整的查詢結果。由此,在充分發揮物化視圖加速查詢優勢的同時,也確保了最新資料的即時可見度。
適用範圍
僅支援日誌庫標準型LogStore,不支援查詢型LogStore、時序庫MetricStore、資料檢視StoreView等。
物化視圖的管理,目前僅支援API的方式。暫不支援在控制台操作 。
使用物化視圖
此處以Java語言為例。
若使用阿里雲帳號預設擁有所有許可權,無需再額外授權。若使用RAM使用者需設定如下許可權:
匯入如下版本的Log ServiceJava SDK。
<dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>aliyun-log</artifactId> <version>0.6.138</version> </dependency>如下樣本中,包含物化視圖的建立、物化視圖列表擷取、物化視圖資訊擷取、刪除物化視圖等操作,請按需修改執行。
代碼中參數擷取方式參考如下:
accessKey與accessId擷取參考建立AccessKey。
host擷取方式:
登入Log Service控制台,在Project列表中,單擊目標Project。
單擊Project名稱右側的
進入專案概覽頁面,在訪問網域名稱中複製公網網域名稱。
import com.aliyun.openservices.log.Client; import com.aliyun.openservices.log.exception.LogException; import com.aliyun.openservices.log.request.CreateMaterializedViewRequest; import com.aliyun.openservices.log.request.ListMaterializedViewsRequest; import com.aliyun.openservices.log.response.ListMaterializedViewsResponse; import java.text.SimpleDateFormat; import java.util.concurrent.TimeUnit; public class MvDemo { static String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID", ""); static String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET", ""); /** * Log Service的服務存取點。此處以杭州為例,其它地區請根據實際情況填寫。 */ static String host = "cn-hangzhou.log.aliyuncs.com"; /** * 建立Log ServiceClient。 */ static Client client = new Client(host, accessId, accessKey); /** * Project名稱。 */ static String projectName = "xxx"; /** * LogStore名稱。 */ static String logstoreName = "xxx"; public static void main(String[] args) throws Exception { String materializedViewName = "test_mv"; createMv(materializedViewName);//建立指定名稱的物化視圖 listMv();//擷取當前project下的物化視圖列表 getMv(materializedViewName);//擷取當前物化視圖資訊 // deleteMv(materializedViewName); //刪除物化視圖 } static int dateStrToSecond(String dateStr) throws Exception { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return (int)TimeUnit.MILLISECONDS.toSeconds(simpleDateFormat.parse(dateStr).getTime()); } static void createMv(String materializedViewName) throws Exception { String originalSql = "* | select count(l1) as cnt, l2 from stability group by l2"; // 請修改為需要通過物化加速的SQL int aggInternalMins = 60; // 定時執行物化的時間周期,單位是分鐘。 int startTime = dateStrToSecond("2025-07-30 00:00:00"); // 開始物化的時間點:是未經處理資料的時間點(資料的寫入時間)。限制只物化這個時間點之後的未經處理資料。 int ttl = 0; // 物化庫的TTL,設為0表示和原始LogStore的TTL保持一致,物化庫的TTL不能小於原始庫的TTL。 //單個project下建立的物化視圖數目不能超過 100個 CreateMaterializedViewRequest request = new CreateMaterializedViewRequest(projectName, materializedViewName, logstoreName, originalSql, aggInternalMins, startTime, ttl); client.createMaterializedView(request); System.out.println("create materialized view " + materializedViewName); } static void listMv() throws LogException { ListMaterializedViewsRequest request = new ListMaterializedViewsRequest(projectName, "", 0, 10);//0,10為分頁查詢參數。 ListMaterializedViewsResponse response = client.listMaterializedViews(request); System.out.println("total materialized view count: " + response.getTotal()); for (String materializedView : response.getMaterializedViews()) { System.out.println(materializedView); } } static void getMv(String materializedViewName) throws Exception { GetMaterializedViewResponse response = client.getMaterializedView(projectName, materializedViewName); System.out.println("get materialized view detail, name: " + materializedViewName); System.out.println("originalSql: " + response.getOriginalSql()); System.out.println("startTime: " + response.getStartTime()); System.out.println("ttl: " + response.getTtl()); } static void deleteMv(String materializedViewName ) throws LogException { client.deleteMaterializedView(projectName, materializedViewName); System.out.println("delete materialized view " + materializedViewName); } }
支援的文法
支援所有的純量涵式和運算式。
支援WHERE條件、GROUP BY、LIMIT、TOP-N等語句。
支援常見的彙總函式,詳細列表如下:
支援的彙總函式 | 文法 |
count(*) count(1) count(x) count_if(boolean expression) max(x) max(x, n) min(x) min(x, n) sum(x) arbitrary(x) | |
approx_distinct(x) approx_distinct(x, e) approx_percentile(x, percentage) |
計費說明
物化視圖計費主要是針對寫入物化庫的資料量,取決於物化視圖對應SQL定時計算的結果資料量。一般來說遠小於原始LogStore的資料量,並按照標準型LogStore的按寫入資料量計費。