全部產品
Search
文件中心

Lindorm:查詢計劃概述

更新時間:Jul 06, 2024

Lindorm支援查看SQL語句在資料庫中的執行過程,協助您定位和排查SQL執行問題。您可以通過EXPLAIN語句查看不同深度的執行計畫,進一步分析最佳化查詢邏輯,以提升查詢效能。

適用引擎

適用於寬表引擎和時序引擎。

背景資訊

查詢計劃(Query Plan)是對一條SQL查詢語句在資料庫中執行過程的描述,也稱為執行計畫(Execution Plan)。在診斷查詢效能時,通常需要先查看目標查詢語句的執行計畫,排查SQL語句的每一步執行是否存在問題。因此,理解查詢計劃是進行SQL語句最佳化的前提條件,同時瞭解查詢計劃中的運算元是理解EXPLAIN命令的關鍵。

查詢計劃深度

Lindorm SQL提供了EXPLAIN語句,方便查看一條查詢語句在SQL引擎中產生的查詢計劃。

共包含三種計劃深度:邏輯計劃、物理計劃和類型計劃。

邏輯計劃

Lindorm SQL僅產生查詢語句未經最佳化器最佳化的、原始的邏輯計劃。

邏輯計劃是SQL引擎根據抽象文法樹進行查詢改寫後產生的查詢計劃。產生邏輯計劃的過程中,資料引擎會改寫部分邏輯操作,使邏輯計劃對SQL引擎後續的最佳化和執行更加友好。例如,將常量運算式直接改寫為一個計算後的常量、將AVG彙總改寫為SUM彙總或COUNT彙總等等。您可以通過在EXPLAIN語句中添加深度運算式來產生邏輯計劃。EXPLAIN的文法介紹,請參見EXPLAIN

假設查詢語句如下:

SELECT LOCATE('9378', p1) AS lp, COUNT(c1) FROM (SELECT * FROM test WHERE p1 like '3_%') GROUP BY lp ORDER BY lp;

產生邏輯計劃:​

EXPLAIN WITHOUT IMPLEMENTATION FOR SELECT LOCATE('9378', p1) AS lp, COUNT(c1) FROM (SELECT * FROM test WHERE p1 like '3_%') GROUP BY lp ORDER BY lp;
********************* 1. row *********************
PLAN: LogicalSort(sort0=[$0], dir0=[ASC])
  LogicalAggregate(group=[{0}], EXPR$1=[COUNT($1)])
    LogicalProject(lp=[LOCATE('9378', $0)], c1=[$1])
      LogicalFilter(condition=[LIKE($0, '3_%')])
        LindormTableScan(table=[[db, test]])

物理計劃

物理計劃是查詢經過最佳化器計算後的執行計算結果。資料庫系統中的最佳化器會基於一定的規則策略或代價策略,為產生的邏輯計劃選擇最適合的執行方式。這樣的執行方式(包括最後被選定的結果,以及候選項)被稱為物理計劃。

執行EXPLAIN語句時,預設返回物理計劃,它包含了SQL引擎的執行運算元以及下推到寬表引擎上的執行運算元。

物理計劃可以很明確地展示SQL查詢語句的執行過程,包括資料的掃描方式、關係運算的執行順序等。

假設查詢語句如下:

SELECT LOCATE('9378', p1) AS lp, COUNT(c1) FROM (SELECT * FROM test WHERE p1 like '3_%') GROUP BY lp ORDER BY lp;

產生物理計劃:

EXPLAIN SELECT LOCATE('9378', p1) AS lp, COUNT(c1) FROM (SELECT * FROM test WHERE p1 like '3_%') GROUP BY lp ORDER BY lp;
********************* 1. row *********************
PLAN: EnumerableSort(sort0=[$0], dir0=[ASC])
  EnumerableAggregate(group=[{0}], EXPR$1=[COUNT($1)])
    EnumerableCalc(expr#0..3=[{inputs}], expr#4=['9378'], expr#5=[LOCATE($t4, $t0)], lp=[$t5], c1=[$t1])
      EnumerableLindormDirectQuery(
explanation=[SELECT p1,c1,c2,c3 from test where ((p1 < 4) AND (p1 >= 3) AND (p1 LIKE 3_%)) supportEmptyResult true
Candidate tables: 
    Data table: test, scores=1..0..1, need query back=false, sort type=FORWARD
Chose data table [test].
---
SELECT p1,c1,c2,c3 from test supportEmptyResult true
SingleScan on test
    ranges: [3\x00, 4\x00]
    filter: ((p1 < 4) AND (p1 >= 3) AND (p1 LIKE 3_%))
])

類型計劃

Lindorm SQL僅產生返回結果集中資料行的列類型。

類型計劃是基於查詢類型的特定查詢計劃。相較於邏輯計劃和物理計劃,類型計劃是最粗糙的一種查詢計劃。您可以通過在EXPLAIN語句中添加深度運算式來組建類型計劃。EXPLAIN的文法介紹,請參見EXPLAIN

假設查詢語句如下:

SELECT LOCATE('9378', p1) AS lp, COUNT(c1) FROM (SELECT * FROM test WHERE p1 like '3_%') GROUP BY lp ORDER BY lp;

組建類型計劃:​

EXPLAIN WITH TYPE FOR SELECT LOCATE('9378', p1) AS lp, COUNT(c1) FROM (SELECT * FROM test WHERE p1 like '3_%') GROUP BY lp ORDER BY lp;
********************* 1. row *********************
PLAN: lp INTEGER NOT NULL,
EXPR$1 BIGINT NOT NULL

解讀執行計畫

以下是Lindorm SQL中組成物理計劃的常用物理運算元。

通用物理運算元

Lindorm SQL實現了一套通用物理運算元供最佳化器產生物理計劃,包括查詢中諸如排序、彙總、投影、運算等通用計算行為。以下是查詢中常見的物理運算元:

  • EnumerableLimit運算元

    通用LIMIT運算元,基於使用者指定的OFFSET和LIMIT對結果集資料進行跳過截取。顯示執行計畫時,會顯示該運算元所需的offsetfetch來源。

  • EnumerableSort運算元

    通用排序運算元,基於使用者指定的ORDER BY運算式對資料進行排序。該預設排序演算法基於TreeMap實現。顯示執行計畫時,會顯示該運算元排序鍵的來源。

  • EnumerableAggregate運算元

    通用彙總運算元,基於使用者指定的彙總函式以及可能存在的分組列對下層運算元迭代返回的資料進行彙總,同時也可用於DISTINCT的實現。顯示執行計畫時,會顯示該運算元的分組鍵、彙總函式相關的運算式。

  • EnumerableCalc運算元

    運算式計算運算元。可以實現常見運算式的執行,如運算運算式、函數(非彙總函式或視窗函數)運算式。此外,對於類似投影、過濾等計算,大多數情況下也是通過EnumerableCalc運算元來實現。

擴充物理運算元

下推運算元EnumerableLindormDirectQuery

EnumerableLindormDirectQuery運算元是Lindorm SQL中通用的擴充運算元,表示查詢中下推到儲存引擎進行計算的部分。該運算元的返回結果包含在explanation欄位中。不同資料引擎中,explanation欄位的資訊可能包含不同的資訊,具體如下:

資料引擎

explanation包含資訊

寬表引擎

返回在寬表引擎上執行的運算內容。包含以下資訊:

  • 索引的選擇。

  • 資料掃描的方式。

  • 資料掃描的範圍。

  • 資料過濾條件。

時序引擎

返回對時序引擎調用的API參數。

時序引擎特有擴充運算元

  • TSDBDataScanRel運算元

    面向Lindorm時序引擎實現最基礎的資料掃描運算元,由邏輯運算元LogicalTableScan轉換而來,表示在某個具體的指標(metric)上執行的Scan操作。該運算元在展示時會包含以下內容:

    • filter:掃描時同時內建的過濾條件。

    • project:上層計划算子運算式與時序表之間的列映射關係。

    • hint:掃描時同時下推的Scan HINT(例如 _l_series_only)。

  • TSDBShowTagRel運算元

    ​面向查詢某個標籤列下所有標籤值的最佳化實現,對標influxDB的SHOW TAG VALUES能力。其在查詢計劃樹(Plan Tree)中的位置與TSDBDataScanRel運算元相似,往往位於計劃樹最下層節點,主要用於標識在資料引擎上掃描資料的方法。只有一種查詢會被最佳化到使用該運算元,即SELECT DISTINCT ${tagkey column} FROM ${table}

  • TSDBAggScanRel運算元

    ​面向Lindorm時序引擎實現的時間軸彙總運算元,由EnumerableAggregation運算元和TSDBDataScanRel運算元合并最佳化而來。

  • EnumerableDownsampleQuery運算元

    EnumerableDownsampleQuery運算元是Lindorm SQL面向SAMPLE BY語句實現的一個運算元。SAMPLE BY語句是面向時序降採樣情境拓展的SQL方言,該語句所有上下文都是拓展出來的,包括其邏輯運算元(LogicalDownsampleQuery)和物理運算元(EnumerableDownsampleQuery)。因此,只有使用SAMPLE BY語句才會產生EnumerableDownsampleQuery運算元。

    ​該運算元在顯示查詢計劃時包含以下欄位:

    • project: 上層計划算子運算式與EnumerableDownsampleQuery運算元之間的列映射關係。

    • filter:隨著降採樣計算一併下推到時序引擎的過濾條件。

    • ds_agg:降採樣函數及其參數。

    • aggregator:當存在可下推到時序引擎執行的跨時間軸彙總時,一併下推的彙總運算元。

    • hint:下推到時序引擎的HINT。