Apache Doris Profile 深度解析:從獲取到分析,解鎖查詢性能優化密碼

在這里插入圖片描述

在 Doris 數據庫中,高效的查詢性能是數據處理的關鍵。當我們遇到查詢緩慢、資源消耗異常等問題時,Doris 提供的 Profile 工具就如同一位 “性能偵探”,能幫我們抽絲剝繭,找到問題根源。今天,我們就來深入聊聊如何分析 Profile,讓 Doris 的查詢性能更上一層樓。

一、Profile:解決查詢性能的利器

Profile 是 Doris 用于記錄和展示查詢執行詳細信息的強大工具,它以樹狀結構將查詢計劃的每個階段(Operator)的執行時間、資源消耗等指標清晰呈現。通過 Profile,我們可以直觀地了解查詢的性能表現,判斷哪些操作耗時過長,是否存在數據傾斜、網絡延遲等問題,從而為優化查詢性能、排查問題提供重要依據。無論是慢查詢分析、性能調優,還是高并發場景下的瓶頸定位,Profile 的分析都貫穿其中,是 Doris 性能調優的核心依據。

對于用戶而言,使用 Profile 有三個核心目標:精準找到查詢的瓶頸點,進行基礎的調優操作,以及基于瓶頸點判斷需要哪些專業人員介入分析(找社區大佬支持)。掌握 Profile 的分析方法,能讓你成為真正懂Doris性能優化的 “行家”。

二、獲取 Profile:不同環境下的操作指南

想要利用 Profile 優化查詢性能,首先要學會如何獲取它。在不同的網絡環境下,獲取 Profile 的方法有所不同。

(一)Doris 集群能夠正常訪問外網

  1. 開啟 Profile 收集參數enable_profile,該參數為 session 變量,不建議全局開啟。在 mysql 客戶端執行set enable_profile=true;,并通過show variables like '%profile%';確認變量是否正常開啟(如果是壓測時候,可以全局開啟)。

  2. 執行對應 Query。需要注意的是,在集群有多個 FE 的情況下,要在開啟 Profile 上報參數的 FE 上執行 Query,因為該參數并非全局生效(session變量,不加global,只在當前環境下生效)。

  3. 獲取 Profile。訪問執行對應 Query 的 FE HTTP 界面(HTTP://FE_IP:HTTP_PORT)的 QueryProfile 頁面,點擊對應 Profile ID 查看 Profile,還可以在 Profile 界面下載對應 Profile。

3.0.3 版本開始支持auto_profile_threshold_ms 變量,這樣就不需要收集所有的query profile了,只需要收集超過指定時間的慢查詢的profile

(二)Doris 集群訪問外網受到限制

當集群不能正常訪問外網時,需要通過 API 的方式獲取 Profile(HTTP://FE_IP:HTTP_PORT/API/Profile?Query_ID=),IP 和端口是指執行對應 Query 的 FE 對應 IP 和端口。具體步驟如下:

  1. 前兩步與正常訪問外網時相同,即開啟enable_profile參數并執行對應 Query。

  2. 找到對應 Query ID,通過show query profile "/";根據對應 Query 找到 Profile ID。

+-----------------------------------+-----------+---------------------+---------------------+-------+------------+------+------------+-------------------------------------------------------+
| Profile ID                        | Task Type | Start Time          | End Time            | Total | Task State | User | Default Db | Sql Statement                                         |
+-----------------------------------+-----------+---------------------+---------------------+-------+------------+------+------------+-------------------------------------------------------+
| 1b0bb22689734d30-bbe56e17c2ff21dc | QUERY     | 2024-02-28 11:00:17 | 2024-02-28 11:00:17 | 7ms   | EOF        | root |            | select id,name from test.test where name like "%RuO%" |
| 202fb174510c4772-965289e8f7f0cf10 | QUERY     | 2024-02-25 19:39:20 | 2024-02-25 19:39:20 | 19ms  | EOF        | root |            | select id,name from test.test where name like "%KJ%"  |
+-----------------------------------+-----------+---------------------+---------------------+-------+------------+------+------------+-------------------------------------------------------+
2 rows in set (0.00 sec)
  1. 查詢 Profile 并將 Profile 重定向到一個文本中,使用命令CURL -X GET -u user:password http://fe_ip:http_port/api/profile?query_id=1b0bb22689734d30-bbe56e17c2ff21dc > test.profile

  2. 返回的 Profile 換行符為n,分析起來不方便,可以在文本編輯工具中將n替換為n,以便更好地查看和分析。

三、Profile 基礎信息總覽:快速定位問題方向

先來看一個 Profile 的基礎信息示例:

Profile ID: 26ec8a4369b46ba-9af43a31cc4f5102- Task Type: QUERY- Start Time: 2025-03-31 17:23:47- End Time: 2025-03-31 17:25:51- Total: 2min4sec [總的耗時]- Task State: OK- User: root- Default Catalog: internal- Default Db: fine_bi_crossdata- Sql Statement: select * from view1 limit 100;
Execution Summary:- Parse SQL Time: 15ms- Nereids Analysis Time: 10ms- Nereids Rewrite Time: 51ms- Nereids Optimize Time: 30ms- Nereids Translate Time: 3ms- Workload Group: normal- Analysis Time: 10ms- Plan Time: 99ms [優化器的耗時,如果這個時間占據單個查詢的比例過大,比如超過20%,需要聯系社區同學分析]- JoinReorder Time: N/A- CreateSingleNode Time: N/A- QueryDistributed Time: N/A- Init Scan Node Time: N/A- Finalize Scan Node Time: N/A- Get Splits Time: N/A [如果是這塊的占比時間比較高的情況,大概率是外表的問題]- Get Partitions Time: N/A- Get Partition Files Time: N/A- Create Scan Range Time: N/A- Get Partition Version Time: 9.561ms- Get Partition Version Count (hasData): 0- Get Partition Version Count: 1- Get Table Version Time: N/A- Get Table Version Count: 0- Schedule Time: 98ms- Fragment Assign Time: 1ms- Fragment Serialize Time: 21ms [這里也類似,如果耗時過多,請也得聯系社區的同學分析了。很可能是有GC了]- Fragment RPC Phase1 Time: 75ms- Fragment RPC Phase2 Time: 1ms- Fragment Compressed Size: 3.92 MB- Fragment RPC Count: 24- Schedule Time Of BE: {...}- Wait and Fetch Result Time: 2min3sec- Fetch Result Time: 2min3sec [BE具體執行的耗時]- Write Result Time: 1ms [回寫mysql的耗時,如果這塊耗時過多,可能是客戶端的瓶頸,分析一下結果集是不是過大]

從這些信息中,我們可以快速判斷問題可能出在 FE 還是 BE 。通常情況下,95% 以上的主要耗時集中在Wait and Fetch Result Time。若 FE 出現問題,常見原因有 GC 問題、鎖問題、CPU 打滿等,這類問題與 FE 的集群負載密切相關,一旦確認是 FE 的問題,需要收集當時的 CPU、內存監控數據進一步分析。

四、定位瓶頸點:Merged Profile 匯總信息

為了更準確地分析性能瓶頸,Doris 提供了各個 operator 聚合后的 Merged Profile 結果。以EXCHANGE_OPERATOR為例:

EXCHANGE_OPERATOR  (id=4):-  BlocksProduced:  sum  0,  avg  0,  max  0,  min  0-  CloseTime:  avg  34.133us,  max  38.287us,  min  29.979us-  ExecTime:  avg  700.357us,  max  706.351us,  min  694.364us-  InitTime:  avg  648.104us,  max  648.604us,  min  647.605us-  MemoryUsage:  sum  ,  avg  ,  max  ,  min -  PeakMemoryUsage:  sum  0.00  ,  avg  0.00  ,  max  0.00  ,  min  0.00 -  OpenTime:  avg  4.541us,  max  5.943us,  min  3.139us-  ProjectionTime:  avg  0ns,  max  0ns,  min  0ns-  RowsProduced:  sum  0,  avg  0,  max  0,  min  0-  WaitForDependencyTime:  avg  0ns,  max  0ns,  min  0ns-  WaitForData0:  avg  9.434ms,  max  9.476ms,  min  9.391ms

Merged Profile 對每個 operator 的核心指標做了合并,核心指標和含義包括:

指標名稱指標含義
BlocksProduced產生的 Data Block 數量
CloseTimeOperator 在 close 階段的耗時
ExecTimeOperator 在各個階段執行的總耗時
InitTimeOperator 在 Init 階段的耗時
MemoryUsageOperator 在執行階段的內存用量
OpenTimeOperator 在 Open 階段的耗時
ProjectionTimeOperator 在做 projection 的耗時
RowsProducedOperator 返回的行數
WaitForDependencyTimeOperator 等待自身執行的條件依賴的時間

我們可以通過以下簡單方法快速定位瓶頸點:

cat profile_b112de34c7a94d2e-a6b773cc1db43602.txt  |grep ExecTime | grep max

找到max耗時最久的時間后,再回頭在 Profile 中查找對應的算子,就能確定查詢的性能瓶頸所在。

例如,通過上述方法找出慢的算子是AGG算子,后續就可以針對AGG算子進行深入分析和調優。

五、基礎調優:對癥下藥,提升性能

Doris 中的查詢主要分為兩類,針對不同類型的查詢,調優方法也有所不同。

(一)單表大寬表分析

對于單表的大寬表分析,優化方法可參考 Doris 查詢優化秘籍(上篇):關鍵優化策略剖析,通過合理設計表結構、選擇合適的索引等方式提升查詢性能。

(二)多表關聯復雜分析

多表關聯的復雜分析中,70% - 80% 的性能問題是由 RuntimeFilter 和 JoinReorder 不合適導致的。

  • RuntimeFilter 調優:在 Profile 中搜索RuntimeFilterState關鍵字,如果發現IsPushDown = falseRuntimeFilter的狀態為NOT_READY,可以通過設置set runtime_filter_wait_infinitely = true,重新驗證是否是 RF 導致的性能問題。

  • Join 方式調優:在 Doris 中,shufflebroadcast是常見的數據分發方式,選擇不當會影響查詢性能。例如,當出現數據傾斜導致Shuffle性能極差時,可以通過指定broadcast join hint來優化,如SELECT COUNT(*) FROM orders o JOIN [broadcast] customer c ON o.customer_number = c.customer_number;

  • Join 順序調優:Doris 中 JOIN 操作建議左表大于右表(或至少左表不小于右表),以優化查詢性能。如果發現max的耗時主要在join上,可以查看join順序是否合理。通過對比HASH_JOIN_OPERATOR(左表)和HASH_JOIN_SINK_OPERATOR(右表)的數據量情況,判斷join順序是否存在問題。若InputRows > ProbeRows,大概率join順序不合理,此時可以請優化器的專家進行分析處理。

  • 并行度調整:當Schedule time占據大量查詢耗時,通常是instance過多,導致rpc、序列化處理的數據量過大。這種情況下,可以考慮調小pipeline的并行度,如設置set global parallel_pipeline_task_num = 1,觀察性能是否改善。

六、深入分析 Profile:常見問題與處理方案

通過 Execution Summary 部分,我們可以初步確定查詢的瓶頸在 FE 還是 BE。若在 BE,我們可以重點分析各個算子的情況。在 2.1 版本的 Profile 經過 merge 后,界面較為精簡,我們可以通過查看每個算子的查詢時間來定位問題。一般來說,ExecTime最大的節點就是最耗時的節點,順著這個 id 繼續分析。如果各個算子耗時相差不大,說明沒有明確的熱點。

以下是一些常見問題的處理方案:

  • 熱點在 nested loop join 上:嘗試修改 sql,將 nested loop join 改為 hash join,可顯著提升性能。

  • 熱點在 join 上

    • 檢查 join order 順序,從條目數上判斷是否合理。若右表條目數顯著大于左表,或左右表數據量相近但右表列數顯著大于左表,可能需要優化器同學介入。

    • 排查 Runtime filter,檢查 rf 是否生效、等待時間是否合理,以及是否存在多余或無用的 rf。

    • 優化 join 列,盡量將 join 列和 group by 列建為非 null,能用定長列就不用變長列。

    • 評估 join 的 shuffle 方式是否合理,考慮使用Broadcastcolocate或優化Bucket shuffle

  • 熱點在 agg 上:參考 join 列的優化方式,調整表結構,如將 group by 的列作為表的分桶列或分區列,可對單表聚合性能提升有顯著效果。

  • scan 上慢

    • 檢查表引擎類型,優先選擇查詢性能較好的duplicate key引擎。

    • 使用select 分桶列,count(*) from table group by 分桶列 order by count(*) desc limit 100;檢查分桶是否有數據傾斜問題。

    • 注意 key 列的順序,因為 Doris 底層存儲引擎按 key 列排序存儲,合理的 key 列順序有助于快速二分查找。

    • 觀察表的 compaction 情況,找到慢 scan 的 tablet,查看 compaction 鏈接,若存在慢副本,可通過set use_fix_replica繞過,并聯系官方同學分析原因。

Profile 是 Doris 性能優化的關鍵利器,掌握它的獲取、分析和調優方法,能讓我們在面對查詢性能問題時游刃有余。希望通過本文的分享,大家都能成為 Doris 性能優化的高手!如果你在使用 Profile 的過程中還有其他問題或經驗,歡迎在評論區留言交流~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/89739.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/89739.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/89739.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

系統架構師

硬件: 運算器:1)算術運算 加減乘除 2)邏輯運算并進行邏輯測試:與或非 組件功能:算術邏輯單元ALU :處理數據 實現對數據的算術運算和邏輯運算 累加寄存器AC 通用寄存器,alu提供工作區 暫存運算結…

Unity HDRP + Azure IoT 工業設備監控系統實例

Unity HDRP Azure IoT 工業設備監控系統實例 下面是一個完整的工業設備監控解決方案,結合Unity HDRP(高清渲染管線)的高質量可視化與Azure IoT的實時數據處理能力。 系統架構 #mermaid-svg-XJnD6acrBbtbqYHW {font-family:"trebuchet…

(超詳細)數據庫項目初體驗:使用C語言連接數據庫完成短地址服務(本地運行版)

數據庫項目初體驗:使用C語言連接數據庫完成短地址服務(本地運行版) 前言:初學者的思考 作為一個剛初學數據庫的小白并且在之前我的博客中我有嘗試使用C語言寫過一個短地址服務,但是使用C語言編寫的短地址服務只有短記…

mysql基礎(一)快速上手篇

連接mysql 使用命令行窗口連接mysql數據庫 語法:mysql –h主機名 –u用戶名 –p密碼 說明:-h參數指定數據庫ip,本地服務器可以用localhost,-u參數指定用戶名,-p參數指定用戶密碼。 注意:-p和密碼值之間…

IntelliJ IDEA 2025- 下載安裝教程圖文版詳細教程(附激活碼)

目錄 寫在前面 一、介紹 二、下載 三、安裝 🏁 寫在最后 寫在前面 > 🚀 初學 Java?或者剛開始寫項目,不知道該選哪個 IDE? 本篇教程手把手教你安裝 IntelliJ IDEA —— JetBrains 出品的頂級 Java 開發環境&a…

數學經濟專業大學四年規劃

數學經濟專業結合了數學的邏輯嚴謹性和經濟學的現實應用性,為學生提供了強大的數理分析能力和經濟洞察力。該專業畢業生在金融科技、量化投資、商業分析等領域具有顯著優勢,尤其在數字經濟時代,這類復合型人才的需求量持續增長。一、數學經濟…

局域網打印機共享怎么設置?如何配置內網本地網絡打印機給異地電腦遠程連接使用打印?

打印機共享怎么設置?如何設置本地內網的網絡打印機共享給其他網絡下電腦連接打印?打印機設置使用以及異地使用打印都是大家比較關注的問題,下面詳細教程中分二步,先講局域網內的打印機共享,再進一步介紹內網打印機地址…

Rust異步爬蟲實現與優化

Rust 語言在爬蟲領域的應用相對較少,盡管 Rust 的 async/await 已穩定,但其與線程安全、Pin 等概念的結合仍較復雜,而爬蟲高度依賴并發處理,進一步提高了開發成本。這就導致了使用Rust語言爬蟲用的人很少。 下面是一個使用 Rust 編…

Electron 安全最佳實踐:構建安全的桌面應用

Electron 是一個流行的框架,允許開發者使用 Web 技術(HTML、CSS、JavaScript)構建跨平臺桌面應用。許多知名應用,如 VS Code、Slack 和 Discord,都基于 Electron 開發。然而,由于其結合了 Node.js&#xff…

MySQL 事務詳解:從基礎操作到隔離級別與 MVCC 原理

前言 首先從概念上進行理解什么是事務,以及事務的4大屬性,知道是什么還要知道為什么? 事務是如何進行操作的,最后在談事務的隔離性、隔離級別(最重要但是也很難理解),理解隔離級別體現在哪里 …

【Unity 編輯器工具開發:GUILayout 與 EditorGUILayout 對比分析】

Unity 編輯器工具開發:GUILayout 與 EditorGUILayout 對比分析 一、核心區別對比 方面GUILayoutEditorGUILayout區別命名空間UnityEngineUnityEditorEditorGUILayout 僅限編輯器環境適用范圍游戲運行時 編輯器工具僅限編輯器工具運行時禁用 EditorGUILayout渲染管…

[附源碼+數據庫+畢業論文]基于Spring+MyBatis+MySQL+Maven+jsp實現的個人財務管理系統,推薦!

摘 要 隨著軟件信息技術的興起,許多手工作業也升級為軟件管理數據,本次針對個人財務數據的管理,開發一款個人財務管理系統,該系統可以解決許多信息管理上面的難題,比如處理數據時間很長,數據存在錯誤不能及…

Compose入門3 - 高仿小紅書 界面

使用compose 實現一個小紅書UI 界面,主要是為了鍛煉 使用compose布局的能力 demo地址:https://github.com/PangHaHa12138/ComposeDemo 先上demo 截圖 下面是完整的compose代碼 package com.example.test001import android.annotation.SuppressLint imp…

mybatis-plus json字段使用typeHandler自動轉換為List

mybatis-plus json字段使用typeHandler自動轉換為List mybatis-plus json字段使用typeHandler自動轉換為List 一、實現思路 1.配置mybatis配置,注入handlermybatis-plus:typeHandlersPackage: com.power.common.core.handler 2.字段頂部增加注解TableField(typeHand…

(C++)學生管理系統(測試2版)(map數組的應用)(string應用)(引用)(C++教學)(C++項目)

1. 頭文件與命名空間 #include <iostream> // 輸入輸出流庫&#xff0c;提供cin/cout等基本I/O功能 #include <map> // 映射容器庫&#xff0c;提供map數據結構&#xff08;鍵值對集合&#xff09; #include <string> // 字符串庫&#xff0c;…

使用assembly解決jar包超大,實現依賴包、前端資源外置部署

成果物需要部署到用戶內網的童鞋應該都遇到過該問題&#xff1a;引入的maven依賴越來越多&#xff0c;jar包越來越大&#xff0c;我之間甚至見過一兩個G的依賴&#xff0c;想改個代碼換到現場測試&#xff0c;包傳到現場要一二十分鐘&#xff0c;真正實現了改代碼兩分鐘分鐘&am…

基于PHP+MySQL實現(Web)英語學習與測試平臺

數據庫課設&#xff1a;英語學習與測試平臺 運行環境要求 PHP7.1 基于 thinkPHP6.0、Layui、Xadmin 開發 主要功能 公共模塊 登錄注冊個人信息修改密碼修改 教師模塊 文章查看發布班級管理測試查看發布批改歷史成績查看 學生模塊 文章查看參與測試查看成績 管理員模塊…

WinForm中Settings.settings和app.config修改后信息不同步到exe.config問題

在 WinForms 項目中&#xff0c;Settings.settings 和 app.config/exe.config 的關系確實容易讓人困惑。以下是問題的根本原因和解決方案&#xff1a; 問題本質 設計時文件&#xff1a;app.config&#xff08;源碼中的配置文件&#xff09;運行時文件&#xff1a;bin/Debug/Yo…

【公司環境下發布個人NPM包完整教程】

&#x1f3e2; 公司環境下發布個人NPM包完整教程 創建時間: 2025年7月2日 適用場景: 公司電腦&#xff0c;需要臨時切換個人賬戶發布npm包 &#x1f3af; 教程概述 場景說明 環境: 公司電腦&#xff0c;已配置公司npm賬戶目標: 臨時使用個人賬戶發布npm包&#xff0c;發布后恢復…

滲透測試中 phpinfo() 的信息利用分析

在滲透測試中&#xff0c;phpinfo() 是一個非常常見卻極具價值的信息泄露點。這個函數的本意是向開發者展示當前 PHP 環境的詳細配置情況&#xff0c;包括編譯選項、擴展模塊、環境變量、系統信息、目錄路徑等。然而一旦該頁面被暴露到互聯網上&#xff0c;攻擊者便可以借此收集…