全部產品
Search
文件中心

ApsaraDB for SelectDB:查詢Profile

更新時間:Jun 25, 2025

通過分析Profile,可以為查詢效能的調優提供參考和依據。本文介紹如何擷取ApsaraDB for SelectDB的查詢Profile。

開啟查詢Profile

通過設定enable_profile變數,開啟查詢Profile。更多變數詳情,請參見查詢變數

SET enable_profile=true;
說明
  • 開啟查詢Profile後,執行查詢時,SelectDB會產生該查詢的一個Profile。

  • Profile包含了一個查詢在各個節點上的具體執行情況,有助於分析查詢瓶頸。

查看查詢Profile

通過以下指令查看當前儲存的所有的查詢Profile。

重要

僅SelectDB版本號碼小於4.0.0的執行個體支援此指令。如果版本號碼大於等於4.0.0,推薦您使用可視化介面預覽或下載Profile資訊。具體操作,請參見查詢審計。您也可通過HTTP介面擷取查詢Profile資訊。具體操作,請參見匯出查詢Profile

SHOW QUERY PROFILE "/"\G;

查詢結果集中,每行對應一個查詢。您可以根據Profile ID,查看對應查詢的Profile具體資訊。

說明

在Profile相關的HTTP介面中,存在Query IDquery_id等描述,他們都代表Profile ID

SHOW QUERY PROFILE "/"\G
*************************** 1. row ***************************
   Profile ID: c257c52f93e149ee-ace8ac14e8c9fef9
    Task Type: QUERY
   Start Time: 2021-04-08 11:30:50
     End Time: 2021-04-08 11:30:50
        Total: 9ms
   Task State: EOF
         User: root
   Default Db: default_cluster:db1
Sql Statement: select tbl1.k1, sum(tbl1.k2) from tbl1 join tbl2 on tbl1.k1 = tbl2.k1 group by tbl1.k1 order by tbl1.k1

使用查詢Profile

您可以通過以下三個步驟,使用查詢Profile的資訊,逐步排查一個SQL的效能瓶頸。

  1. 查看整體執行計畫樹。

    這一步主要用於從整體分析執行計畫,並查看每個Fragment的執行耗時。查詢結果中每個節點都標註了自己所屬的Fragment,並且在每個Fragment的Sender節點標註了該Fragment的執行耗時。這個耗時是Fragment下所有執行單元的執行耗時中最長的一個。該統計報告有助於從整體角度發現最耗時的Fragment,查詢樣本如下。

    SHOW QUERY PROFILE "/c257c52f93e149ee-ace8ac14e8c9fef9"\G
    *************************** 1. row ***************************
    Fragments:
                 ┌──────────────────────┐
                 │[-1: DataBufferSender]│
                 │Fragment: 0           │
                 │MaxActiveTime: 6.626ms│
                 └──────────────────────┘
                             │
                   ┌──────────────────┐
                   │[9: EXCHANGE_NODE]│
                   │Fragment: 0       │
                   └──────────────────┘
                             │
                 ┌──────────────────────┐
                 │[9: DataStreamSender] │
                 │Fragment: 1           │
                 │MaxActiveTime: 5.449ms│
                 └──────────────────────┘
                             │
                     ┌──────────────┐
                     │[4: SORT_NODE]│
                     │Fragment: 1   │
                     └──────────────┘
                            ┌┘
                 ┌─────────────────────┐
                 │[8: AGGREGATION_NODE]│
                 │Fragment: 1          │
                 └─────────────────────┘
                            └┐
                   ┌──────────────────┐
                   │[7: EXCHANGE_NODE]│
                   │Fragment: 1       │
                   └──────────────────┘
                             │
                 ┌──────────────────────┐
                 │[7: DataStreamSender] │
                 │Fragment: 2           │
                 │MaxActiveTime: 3.505ms│
                 └──────────────────────┘
                            ┌┘
                 ┌─────────────────────┐
                 │[3: AGGREGATION_NODE]│
                 │Fragment: 2          │
                 └─────────────────────┘
                            │
                  ┌───────────────────┐
                  │[2: HASH_JOIN_NODE]│
                  │Fragment: 2        │
                  └───────────────────┘
               ┌────────────┴────────────┐
     ┌──────────────────┐      ┌──────────────────┐
     │[5: EXCHANGE_NODE]│      │[6: EXCHANGE_NODE]│
     │Fragment: 2       │      │Fragment: 2       │
     └──────────────────┘      └──────────────────┘
               │                         │
    ┌─────────────────────┐ ┌────────────────────────┐
    │[5: DataStreamSender]│ │[6: DataStreamSender]   │
    │Fragment: 4          │ │Fragment: 3             │
    │MaxActiveTime: 1.87ms│ │MaxActiveTime: 636.767us│
    └─────────────────────┘ └────────────────────────┘
               │                        ┌┘
     ┌───────────────────┐    ┌───────────────────┐
     │[0: OLAP_SCAN_NODE]│    │[1: OLAP_SCAN_NODE]│
     │Fragment: 4        │    │Fragment: 3        │
     └───────────────────┘    └───────────────────┘
               │                        │
        ┌─────────────┐          ┌─────────────┐
        │[OlapScanner]│          │[OlapScanner]│
        │Fragment: 4  │          │Fragment: 3  │
        └─────────────┘          └─────────────┘
               │                        │
      ┌─────────────────┐      ┌─────────────────┐
      │[SegmentIterator]│      │[SegmentIterator]│
      │Fragment: 4      │      │Fragment: 3      │
      └─────────────────┘      └─────────────────┘
     
    1 row in set (0.02 sec)
  2. 查看具體Fragment下的執行單元列表。

    例如上述樣本中Fragment1耗時最長,您可以繼續查看Fragment1的執行單元列表。查詢中Fragment 1上所有的3個執行單元所在的執行節點和耗時,查詢樣本如下。

    SHOW QUERY PROFILE "/c257c52f93e149ee-ace8ac14e8c9fef9/1";
    +-----------------------------------+-------------------+------------+
    | Instances                         | Host              | ActiveTime |
    +-----------------------------------+-------------------+------------+
    | c257c52f93e149ee-ace8ac14e8c9ff03 | 10.200.00.01:9060 | 5.449ms    |
    | c257c52f93e149ee-ace8ac14e8c9ff05 | 10.200.00.02:9060 | 5.367ms    |
    | c257c52f93e149ee-ace8ac14e8c9ff04 | 10.200.00.03:9060 | 5.358ms    |
    +-----------------------------------+-------------------+------------+ 
  3. 查看具體執行單元。

    您可以繼續查看某一個具體的執行單元上各個運算元的詳細Profile。例如查詢Fragment1中,執行單元c257c52f93e149ee-ace8ac14e8c9ff03的各個運算元的具體Profile,查詢樣本如下。

    SHOW QUERY PROFILE "/c257c52f93e149ee-ace8ac14e8c9fef9/1/c257c52f93e149ee-ace8ac14e8c9ff03"\G
    *************************** 1. row ***************************
    Instance:
     ┌───────────────────────────────────────┐
     │[9: DataStreamSender]                  │
     │(Active: 37.222us, non-child: 0.40)    │
     │  - Counters:                          │
     │      - BytesSent: 0.00                │
     │      - IgnoreRows: 0                  │
     │      - OverallThroughput: 0.0 /sec    │
     │      - PeakMemoryUsage: 8.00 KB       │
     │      - SerializeBatchTime: 0ns        │
     │      - UncompressedRowBatchSize: 0.00 │
     └───────────────────────────────────────┘
                         └┐
                          │
        ┌──────────────────────────────────┐
        │[4: SORT_NODE]                    │
        │(Active: 5.421ms, non-child: 0.71)│
        │  - Counters:                     │
        │      - PeakMemoryUsage: 12.00 KB │
        │      - RowsReturned: 0           │
        │      - RowsReturnedRate: 0       │
        └──────────────────────────────────┘
                         ┌┘
                         │
       ┌───────────────────────────────────┐
       │[8: AGGREGATION_NODE]              │
       │(Active: 5.355ms, non-child: 10.68)│
       │  - Counters:                      │
       │      - BuildTime: 3.701us         │
       │      - GetResultsTime: 0ns        │
       │      - HTResize: 0                │
       │      - HTResizeTime: 1.211us      │
       │      - HashBuckets: 0             │
       │      - HashCollisions: 0          │
       │      - HashFailedProbe: 0         │
       │      - HashFilledBuckets: 0       │
       │      - HashProbe: 0               │
       │      - HashTravelLength: 0        │
       │      - LargestPartitionPercent: 0 │
       │      - MaxPartitionLevel: 0       │
       │      - NumRepartitions: 0         │
       │      - PartitionsCreated: 16      │
       │      - PeakMemoryUsage: 34.02 MB  │
       │      - RowsProcessed: 0           │
       │      - RowsRepartitioned: 0       │
       │      - RowsReturned: 0            │
       │      - RowsReturnedRate: 0        │
       │      - SpilledPartitions: 0       │
       └───────────────────────────────────┘
                         └┐
                          │
    ┌──────────────────────────────────────────┐
    │[7: EXCHANGE_NODE]                        │
    │(Active: 4.360ms, non-child: 46.84)       │
    │  - Counters:                             │
    │      - BytesReceived: 0.00               │
    │      - ConvertRowBatchTime: 387ns        │
    │      - DataArrivalWaitTime: 4.357ms      │
    │      - DeserializeRowBatchTimer: 0ns     │
    │      - FirstBatchArrivalWaitTime: 4.356ms│
    │      - PeakMemoryUsage: 0.00             │
    │      - RowsReturned: 0                   │
    │      - RowsReturnedRate: 0               │
    │      - SendersBlockedTotalTimer(*): 0ns  │
    └──────────────────────────────────────────┘

匯出查詢Profile

如果您需要匯出查詢Profile的資訊以便進行分析,可以按照以下步驟操作。

重要

如果SelectDB版本號碼大於等於4.0.0,推薦您使用可視化介面預覽或下載Profile資訊。具體操作,請參見查詢審計。僅SelectDB版本號碼小於4.0.0的執行個體,採用如下指令方式匯出查詢Profile。

  1. 開啟查詢Profile。

    SET enable_profile=true;
  2. 執行查詢。

    以下為查詢樣本,請替換為您的實際 SQL 查詢。

    -- 發送SQL請求,此時查詢的Profile資訊會被記錄
    SELECT count(1) FROM test_table LIMIT 10;
  3. 擷取Profile ID。

    SelectDB 4.0.x版本

    SelectDB 4.0版本及後續版本擷取樣本,其中Query IDProfile ID

    curl -u'<userName>:<userPassword>' "http://<selectdbAddress>:<httpPort>/rest/v2/manager/query/query_info?is_all_node=true" 
    
    # Response
    {
       "msg": "success",  
        "code": 0,  
        "data": {  
            "column_names": [  
                "Query ID",  
                "FE Node",  
                "Query User",  
                "Execution Database",  
                "Sql",  
                "Query Type",  
                "Start Time",  
                "End Time",  
                "Execution Duration",  
                "Status"  
            ],  
            "rows": [  
                [  
                    ...  
                ]  
            ]  
        },  
        "count": 0  
    }

    SelectDB 3.0.x版本

    SelectDB 3.0版本擷取樣本:

    SHOW QUERY PROFILE "/";
    +-----------------------------------+-----------+---------------------+---------------------+-------+------------+-------+------------------------------------+-------------------------------+
    | Profile ID                        | Task Type | Start Time          | End Time            | Total | Task State | User  | Default Db                         | Sql Statement                 |
    +-----------------------------------+-----------+---------------------+---------------------+-------+------------+-------+------------------------------------+-------------------------------+
    | b9c9ba063d9d4365-97878361371e757a | QUERY     | 2024-02-07 17:40:04 | 2024-02-07 17:40:04 | 32ms  | EOF        | admin | default_cluster:information_schema | select * from user_privileges |
    | 8800c306137e4072-9bb1ed419f4ac9f2 | QUERY     | 2024-02-07 17:40:00 | 2024-02-07 17:40:00 | 3ms   | ERR        | admin | default_cluster:information_schema | select * from user_priveleges |
    | e2efdd1a996c4de2-ab939ad49b409990 | QUERY     | 2024-02-07 17:39:51 | 2024-02-07 17:39:51 | 13ms  | EOF        | admin |                                    | SELECT DATABASE()             |
    +-----------------------------------+-----------+---------------------+---------------------+-------+------------+-------+------------------------------------+-------------------------------+
  4. 通過curl擷取Profile ID對應的Profile資訊。

    curl -u'<userName>:<userPassword>' "http://<selectdbAddress>:<httpPort>/api/profile?query_id=<query_id>" 
    
    # 可使用重新導向符號輸出到檔案
    curl -u'<userName>:<userPassword>' "http://<selectdbAddress>:<httpPort>/api/profile?query_id=<query_id>" > res.txt

    參數說明

    參數名稱

    參數說明

    userName

    SelectDB使用者名稱。

    userPassword

    SelectDB密碼。

    selectdbAddress

    SelectDB串連地址。

    httpPort

    SelectDB的HTTP連接埠,預設為8080。

    query_id

    查詢語句的Profile ID。

  5. (可選)若使用重新導向符號儲存為檔案,推薦進行格式化轉換,以方便查看。

    sudo sed -r 's/\\n/\n/g' res.txt | sed -r 's/\\t/\t/g' > new.txt

Profile參數解析

以下對收集的統計資訊參數進行說明。

Fragment

參數名稱

參數說明

AverageThreadTokens

執行Fragment使用線程數目,不包含線程池的使用方式。

Buffer Pool PeakReservation

Buffer Pool使用的記憶體的峰值。

MemoryLimit

查詢時的記憶體限制。

PeakMemoryUsage

整個執行單元在查詢時記憶體使用量的峰值。

RowsProduced

處理列的行數。

BlockMgr

參數名稱

參數說明

BlocksCreated

BlockMgr建立的Blocks數目。

BlocksRecycled

重用的Blocks數目。

BytesWritten

總的落盤寫資料量。

MaxBlockSize

單個Block的大小。

TotalReadBlockTime

讀Block的總耗時。

DataStreamSender

參數名稱

參數說明

BytesSent

發送的總資料量 = 接受者×發送資料量。

IgnoreRows

過濾的行數。

LocalBytesSent

記錄資料在Exchange過程中,本機節點的自發自收資料量。

OverallThroughput

總的輸送量 = BytesSent/時間。

SerializeBatchTime

發送資料序列化消耗的時間。

UncompressedRowBatchSize

發送資料壓縮前的RowBatch的大小。

ODBC_TABLE_SINK

參數名稱

參數說明

NumSentRows

寫入外表的總行數。

TupleConvertTime

發送資料序列化為Insert語句的耗時。

ResultSendTime

通過ODBC Driver寫入的耗時。

EXCHANGE_NODE

參數名稱

參數說明

BytesReceived

通過網路接收的資料量大小。

MergeGetNext

當下層節點存在排序時,會在EXCHANGE NODE進行統一的歸併排序,輸出有序結果。該指標記錄了Merge排序的總耗時,包含了MergeGetNextBatch耗時。

MergeGetNextBatch

Merge節點取資料的耗時。如果為單層Merge排序,則取資料的對象為網路隊列;若為多層Merge排序,則取資料對象為Child Merger。

ChildMergeGetNext

當下層的發送資料的Sender過多時,單線程的Merge會成為效能瓶頸,SelectDB會啟動多個Child Merge線程並行歸併排序。該數值記錄了Child Merge的排序耗時,是多個線程的累加值。

ChildMergeGetNextBatch

Child Merge節點從取資料的耗時,如果耗時過大,說明下層的資料發送節點可能存在瓶頸。

DataArrivalWaitTime

等待Sender發送資料的總時間。

FirstBatchArrivalWaitTime

等待第一個Batch從Sender擷取的時間。

DeserializeRowBatchTimer

還原序列化網路資料的耗時。

SendersBlockedTotalTimer(*)

DataStreamRecv的隊列的記憶體被打滿,Sender端等待的耗時。

ConvertRowBatchTime

接收資料轉為RowBatch的耗時。

RowsReturned

接收行的數目。

RowsReturnedRate

接收行的速率。

SORT_NODE

參數名稱

參數說明

InMemorySortTime

記憶體中排序的耗時。

InitialRunsCreated

初始化排序的趟數(若為記憶體內排序,則該數為1)。

SortDataSize

總的排序資料量。

MergeGetNext

MergeSort從多個sort_run擷取下一個Batch的耗時(僅在落盤時計時)。

MergeGetNextBatch

MergeSort提取下一個sort_run的Batch的耗時(僅在落盤時計時)。

TotalMergesPerformed

進行外排Merge的次數。

AGGREGATION_NODE

參數名稱

參數說明

PartitionsCreated

彙總查詢拆分成Partition的個數。

GetResultsTime

從各個partition之中擷取彙總結果的時間。

HTResizeTime

HashTable進行resize消耗的時間。

HTResize

HashTable進行resize的次數。

HashBuckets

HashTable中Buckets的個數。

HashBucketsWithDuplicate

HashTable有DuplicateNode的Buckets的個數。

HashCollisions

HashTable產生雜湊衝突的次數。

HashDuplicateNodes

HashTable出現Buckets相同DuplicateNode的個數。

HashFailedProbe

HashTable Probe操作失敗的次數。

HashFilledBuckets

HashTable填入資料的Buckets數目。

HashProbe

HashTable查詢的次數。

HashTravelLength

HashTable查詢時移動的步數。

HASH_JOIN_NODE

參數名稱

參數說明

ExecOption

對右子節點構造HashTable的方式(同步or非同步),Join中右子節點可能是表或子查詢,左子節點同理。

BuildBuckets

HashTable中Buckets的個數。

BuildRows

HashTable的行數。

BuildTime

構造HashTable的耗時。

LoadFactor

HashTable的負載因子(即非空Buckets的數量)。

ProbeRows

遍曆左子節點進行Hash Probe的行數。

ProbeTime

遍曆左子節點進行Hash Probe的耗時,不包括對左子節點RowBatch調用GetNext的耗時。

PushDownComputeTime

謂詞下推條件計算耗時。

PushDownTime

謂詞下推的總耗時,Join時對滿足要求的右子節點,轉為左子節點的in查詢。

CROSS_JOIN_NODE

參數名稱

參數說明

ExecOption

對右子節點構造RowBatchList的方式(同步or非同步)。

BuildRows

RowBatchList的行數(即右子節點的行數)。

BuildTime

構造RowBatchList的耗時。

LeftChildRows

左子節點的行數。

LeftChildTime

遍曆左子節點和右子節點求笛卡爾積的耗時,不包括對左子節點RowBatch調用GetNext的耗時。

UNION_NODE

參數名稱

參數說明

MaterializeExprsEvaluateTime

Union兩端欄位類型不一致時,類型轉換運算式計算及物化結果的耗時。

ANALYTIC_EVAL_NODE

參數名稱

參數說明

EvaluationTime

分析函數(視窗函數)計算總耗時。

GetNewBlockTime

初始化時申請一個新的Block的耗時,Block用來緩衝Rows視窗或整個分區,用於分析Function Compute。

PinTime

後續申請新的Block或將寫入磁碟的Block重新讀取回記憶體的耗時。

UnpinTime

對暫不需要使用的Block或當前操作符記憶體壓力大時,將Block的資料刷入磁碟的耗時。

OLAP_SCAN_NODE

OLAP_SCAN_NODE節點負責具體的資料掃描任務。一個OLAP_SCAN_NODE會產生一個或多個OlapScanner。每個Scanner線程負責掃描部分資料。

查詢中的部分或全部謂詞條件會推送給OLAP_SCAN_NODE。這些謂詞條件中一部分會繼續下推給儲存引擎,以便利用儲存引擎的索引進行資料過濾。另一部分會保留在OLAP_SCAN_NODE中,用於過濾從儲存引擎中返回的資料。

OLAP_SCAN_NODE節點的Profile通常用於分析資料掃描的效率,依據調用關係分為OLAP_SCAN_NODEOlapScannerSegmentIterator三層。

一個典型的OLAP_SCAN_NODE節點的Profile如下。部分指標會因儲存格式的不同(V1或V2)而有不同含義。

OLAP_SCAN_NODE (id=0):(Active: 1.2ms, % non-child: 0.00%)
  - BytesRead: 265.00 B                 # 從資料檔案中讀取到的資料量。假設讀取到了是10個32位整型,則資料量為 10 * 4B = 40 Bytes。這個資料僅表示資料在記憶體中全展開的大小,並不代表實際的 IO 大小。 
  - NumDiskAccess: 1                    # 該 ScanNode 節點涉及到的磁碟數量。
  - NumScanners: 20                     # 該 ScanNode 產生的 Scanner 數量。
  - PeakMemoryUsage: 0.00               # 查詢時記憶體使用量的峰值,暫未使用
  - RowsRead: 7                         # 從儲存引擎返回到 Scanner 的行數,不包括經 Scanner 過濾的行數。
  - RowsReturned: 7                     # 從 ScanNode 返回給上層節點的行數。
  - RowsReturnedRate: 6.979K /sec       # RowsReturned/ActiveTime
  - TabletCount : 20                    # 該 ScanNode 涉及的 Tablet 數量。
  - TotalReadThroughput: 74.70 KB/sec   # BytesRead除以該節點啟動並執行總時間(從Open到Close),對於IO受限的查詢,接近磁碟的總輸送量。
  - ScannerBatchWaitTime: 426.886us     # 用於統計transfer 線程等待scaner 線程返回rowbatch的時間。
  - ScannerWorkerWaitTime: 17.745us     # 用於統計scanner thread 等待線程池中可用背景工作執行緒的時間。
  OlapScanner:
    - BlockConvertTime: 8.941us         # 將向量化Block轉換為行結構的 RowBlock 的耗時。向量化 Block 在 V1 中為 VectorizedRowBatch,V2中為 RowBlockV2。
    - BlockFetchTime: 468.974us         # Rowset Reader 擷取 Block 的時間。
    - ReaderInitTime: 5.475ms           # OlapScanner 初始化 Reader 的時間。V1 中包括組建 MergeHeap 的時間。V2 中包括產生各級 Iterator 並讀取第一組Block的時間。
    - RowsDelFiltered: 0                # 包括根據 Tablet 中存在的 Delete 資訊過濾掉的行數,以及 unique key 模型下對被標記的刪除行過濾的行數。
    - RowsPushedCondFiltered: 0         # 根據傳遞下推的謂詞過濾掉的條件,比如 Join 計算中從 BuildTable 傳遞給 ProbeTable 的條件。該數值不準確,因為如果過濾效果差,就不再過濾了。
    - ScanTime: 39.24us                 # 從 ScanNode 返回給上層節點的時間。
    - ShowHintsTime_V1: 0ns             # V2 中無意義。V1 中讀取部分資料來進行 ScanRange 的切分。
    SegmentIterator:
      - BitmapIndexFilterTimer: 779ns   # 利用 bitmap 索引過濾資料的耗時。
      - BlockLoadTime: 415.925us        # SegmentReader(V1) 或 SegmentIterator(V2) 擷取 block 的時間。
      - BlockSeekCount: 12              # 讀取 Segment 時進行 block seek 的次數。
      - BlockSeekTime: 222.556us        # 讀取 Segment 時進行 block seek 的耗時。
      - BlocksLoad: 6                   # 讀取 Block 的數量
      - CachedPagesNum: 30              # 僅 V2 中,當開啟 PageCache 後,命中 Cache 的 Page 數量。
      - CompressedBytesRead: 0.00       # V1 中,從檔案中讀取的解壓前的資料大小。V2 中,讀取到的沒有命中 PageCache 的 Page 的壓縮前的大小。
      - DecompressorTimer: 0ns          # 資料解壓耗時。
      - IOTimer: 0ns                    # 實際從作業系統讀取資料的 IO 時間。
      - IndexLoadTime_V1: 0ns           # 僅 V1 中,讀取 Index Stream 的耗時。
      - NumSegmentFiltered: 0           # 在產生 Segment Iterator 時,通過列統計資訊和查詢條件,完全過濾掉的 Segment 數量。
      - NumSegmentTotal: 6              # 查詢涉及的所有 Segment 數量。
      - RawRowsRead: 7                  # 儲存引擎中讀取的原始行數。詳情見下文。
      - RowsBitmapIndexFiltered: 0      # 僅 V2 中,通過 Bitmap 索引過濾掉的行數。
      - RowsBloomFilterFiltered: 0      # 僅 V2 中,通過 BloomFilter 索引過濾掉的行數。
      - RowsKeyRangeFiltered: 0         # 僅 V2 中,通過 SortkeyIndex 索引過濾掉的行數。
      - RowsStatsFiltered: 0            # V2 中,通過 ZoneMap 索引過濾掉的行數,包含刪除條件。V1 中還包含通過 BloomFilter 過濾掉的行數。
      - RowsConditionsFiltered: 0       # 僅 V2 中,通過各種列索引過濾掉的行數。
      - RowsVectorPredFiltered: 0       # 通過向量化條件過濾操作過濾掉的行數。
      - TotalPagesNum: 30               # 僅 V2 中,讀取的總 Page 數量。
      - UncompressedBytesRead: 0.00     # V1 中為讀取的資料檔案解壓後的大小(如果檔案無需解壓,則直接統計檔案大小)。V2 中,僅統計未命中 PageCache 的 Page 解壓後的大小(如果Page無需解壓,直接統計Page大小)
      - VectorPredEvalTime: 0ns         # 向量化條件過濾操作的耗時。
      - ShortPredEvalTime: 0ns          # 短路謂詞過濾操作的耗時。
      - PredColumnReadTime: 0ns         # 謂詞列讀取的耗時。
      - LazyReadTime: 0ns               # 非謂詞列讀取的耗時。
      - OutputColumnTime: 0ns           # 物化列的耗時。

通過Profile中資料行數相關指標可以推斷謂詞條件下推和索引使用方式。如下對Segment V2格式資料讀取流程中的Profile進行說明。Segment V1格式中,這些指標的含義略有不同。

Init階段

  1. 當讀取一個V2格式的Segment時,若查詢存在key_ranges(首碼key組成的查詢範圍),首先通過SortkeyIndex索引過濾資料,過濾的行數記錄在RowsKeyRangeFiltered

  2. 對查詢條件中含有Bitmap索引的列,使用Bitmap索引進行精確過濾,過濾的行數記錄在RowsBitmapIndexFiltered

  3. 按查詢條件中的等值(eq,in,is)條件,使用BloomFilter索引過濾資料,記錄在RowsBloomFilterFilteredRowsBloomFilterFiltered的值是Segment的總行數(而不是Bitmap索引過濾後的行數)和經過BloomFilter過濾後剩餘行數的差值,因此BloomFilter過濾的資料可能會和Bitmap過濾的資料有重疊。

  4. 按查詢條件和刪除條件,使用ZoneMap索引過濾資料,記錄在RowsStatsFiltered

  5. RowsConditionsFiltered是各種索引過濾的行數,包含了RowsBloomFilterFilteredRowsStatsFiltered的值。

Next階段

  • Next階段刪除條件過濾的行數,記錄在RowsDelFiltered。因該刪除條件實際過濾的行數,分別記錄在RowsStatsFilteredRowsDelFiltered中。

  • RawRowsRead是經過上述過濾後,最終需要讀取的行數。

  • RowsRead是最終返回給Scanner的行數。RowsRead通常小於RawRowsRead,這是因為從儲存引擎返回到Scanner可能會經過一次資料彙總。如果RawRowsReadRowsRead差距較大,則說明大量的行被彙總,而彙總可能比較耗時。

  • RowsReturned是ScanNode最終返回給上層節點的行數。RowsReturned通常也會小於RowsRead。因為在Scanner上會有一些沒有下推給儲存引擎的謂詞條件,這通常意味著一次過濾。如果RowsReadRowsReturned差距較大,則意味著Scanner中進行了大批量的行過濾。這說明很多選擇度高的謂詞條件並沒有推送給儲存引擎,而在Scanner中的過濾效率會比在儲存引擎中過濾效率差。

通過以上指標,可以大致分析出儲存引擎處理的行數以及最終過濾後的結果行數大小。通過Rows***Filtered這組指標,也可以分析查詢條件是否下推到了儲存引擎,以及不同索引的過濾效果。

其他指標

還可以通過如下幾個指標進行分析。

  • OlapScanner下的很多指標,如IOTimerBlockFetchTime等是所有Scanner線程指標的累加,因此數值可能會比較大。並且因為Scanner線程非同步讀取資料,所以這些累加指標只能反映Scanner累加的工作時間,並不直接代表ScanNode的耗時。ScanNode在整個查詢計劃中的耗時佔比為Active欄位記錄的值。有時會出現例如IOTimer有幾十秒,而Active實際只有幾秒鐘。這種情況可能有以下幾個原因。

    • IOTimer為多個Scanner的累加時間,而Scanner數量較多。

    • 上層節點比較耗時。例如上層節點耗時100秒,而底層ScanNode只需10秒。則反映在Active的欄位可能只有幾毫秒。因為在上層處理資料的同時,ScanNode已經非同步進行了資料掃描並準備好了資料。當上層節點從ScanNode擷取資料時,可以擷取到已經準備好的資料,因此Active時間很短。

  • NumScanners表示Scanner提交到線程池的Task個數,由RuntimeState中的線程池調度。doris_scanner_thread_pool_thread_numdoris_scanner_thread_pool_queue_size兩個參數分別控制線程池的大小和隊列長度。線程數過多或過少都會影響查詢效率。同時可以用一些匯總指標除以線程數來大致的估算每個線程的耗時。

  • TabletCount表示需要掃描的Tablet數量。數量過多可能意味著需要大量的隨機讀取和資料合併操作。

  • UncompressedBytesRead間接反映了讀取的資料量。如果該數值較大,說明可能有大量的IO操作。

  • CachedPagesNumTotalPagesNum可以查看命中PageCache的情況。命中率越高,說明IO和解壓操作耗時越少。

Buffer pool

參數名稱

參數說明

AllocTime

記憶體配置耗時。

CumulativeAllocationBytes

累計記憶體配置的量。

CumulativeAllocations

累計的記憶體配置次數。

PeakReservation

Reservation的峰值。

PeakUnpinnedBytes

Unpin的記憶體資料量。

PeakUsedReservation

Reservation的記憶體使用量量。

ReservationLimit

BufferPool的Reservation的限制量。