DRDS分布式SQL引擎—执行计划介绍
摘要:?本文著重介紹 DRDS 執(zhí)行計(jì)劃中各個(gè)操作符的含義,以便用戶通過(guò)查詢計(jì)劃了解 SQL 執(zhí)行流程,從而有針對(duì)性的調(diào)優(yōu) SQL。
DRDS分布式SQL引擎 — 執(zhí)行計(jì)劃介紹
前言
數(shù)據(jù)庫(kù)系統(tǒng)中,執(zhí)行計(jì)劃是對(duì) SQL 如何執(zhí)行的形式化表示,往往由若干關(guān)系操作符構(gòu)成,用戶可以通過(guò)對(duì)應(yīng)的 EXPLAIN 命令查看,并通過(guò)執(zhí)行計(jì)劃大致了解 SQL 的執(zhí)行過(guò)程和執(zhí)行方式,如全表掃描還是索引掃描,歸并連接還是哈希連接等。執(zhí)行計(jì)劃可以為用戶進(jìn)行 SQL 調(diào)優(yōu)提供重要依據(jù)。
DRDS 執(zhí)行計(jì)劃
與多數(shù)數(shù)據(jù)庫(kù)系統(tǒng)類似,DRDS 在處理 SQL 時(shí),會(huì)通過(guò)優(yōu)化器生成執(zhí)行計(jì)劃,該執(zhí)行計(jì)劃由關(guān)系操作符構(gòu)成一個(gè)樹(shù)形結(jié)構(gòu),反映 DRDS 如何執(zhí)行 SQL 語(yǔ)句;不同的是,DRDS 本身不存儲(chǔ)數(shù)據(jù),更側(cè)重考慮分布式環(huán)境中的網(wǎng)絡(luò) IO 開(kāi)銷,將運(yùn)算下推到各個(gè)分庫(kù)(如 RDS/MySQL)執(zhí)行,從而提升 SQL 執(zhí)行效率。用戶可通過(guò) EXPLAIN 命令查看 SQL 的執(zhí)行計(jì)劃。
本文著重介紹 DRDS 執(zhí)行計(jì)劃中各個(gè)操作符的含義,以便用戶通過(guò)查詢計(jì)劃了解 SQL 執(zhí)行流程,從而有針對(duì)性的調(diào)優(yōu) SQL。文中示例均基于如下表結(jié)構(gòu):
CREATE TABLE `sbtest1` (`id` INT(10) UNSIGNED NOT NULL,`k` INT(10) UNSIGNED NOT NULL DEFAULT '0',`c` CHAR(120) NOT NULL DEFAULT '',`pad` CHAR(60) NOT NULL DEFAULT '',KEY `xid` (`id`),KEY `k_1` (`k`) ) dbpartition BY HASH (`id`) tbpartition BY HASH (`id`) tbpartitions 4先通過(guò)一個(gè)例子整體了解 DRDS 執(zhí)行計(jì)劃的樹(shù)形結(jié)構(gòu)。
mysql> explain select a.k, count(*) cnt from sbtest1 a, sbtest1 b where a.id = b.k and a.id > 1000 group by k having cnt > 1300 order by cnt limit 5, 10; +---------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +---------------------------------------------------------------------------------------------------------------------------------------------------+ | TmpSort(sort="cnt ASC", offset=?2, fetch=?3) | | Filter(condition="cnt > ?1") | | Aggregate(group="k", cnt="COUNT()") | | BKAJoin(id="id", k="k", c="c", pad="pad", id0="id0", k0="k0", c0="c0", pad0="pad0", condition="id = k", type="inner") | | MergeSort(sort="k ASC") | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?) ORDER BY `k`") | | UnionAll(concurrent=true) | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE ((`k` > ?) AND (`k` IN ('?')))") | | HitCache:false | +---------------------------------------------------------------------------------------------------------------------------------------------------+ 9 rows in set (0.01 sec)如上,DRDS EXPLAIN 的結(jié)果總體分為兩部分:執(zhí)行計(jì)劃和其他信息。
執(zhí)行計(jì)劃
執(zhí)行計(jì)劃以縮進(jìn)形式表示操作符之間的 "父-子" 關(guān)系。示例中,Filter 是 TmpSort 的子操作符,同時(shí)是 Aggregate 的父操作符。從真正執(zhí)行的角度看,每個(gè)操作符均從其子操作符中獲取數(shù)據(jù),經(jīng)當(dāng)前操作符處理,輸出給其父操作符。為方便理解,將以上執(zhí)行計(jì)劃轉(zhuǎn)換為更加直觀的樹(shù)形結(jié)構(gòu):
其他信息
除執(zhí)行計(jì)劃外,EXPLAIN 結(jié)果中還會(huì)有一些額外信息,目前僅有一項(xiàng) `HitCache` 。需要說(shuō)明的是,DRDS 會(huì)默認(rèn)開(kāi)啟 PlanCache 功能,`HitCache` 表示當(dāng)前 SQL 是否命中 PlanCache。開(kāi)啟 PlanCache 后,DRDS 會(huì)對(duì) SQL 做參數(shù)化處理,參數(shù)化會(huì)將 SQL 中的大部分常量用???替換,并構(gòu)建一個(gè)參數(shù)列表。在執(zhí)行計(jì)劃中的體現(xiàn)就是,LogicalView 的?sql?中會(huì)有???,在部分操作符中會(huì)有類似??2?的字樣,這里的?2?表示其在參數(shù)列表中的下標(biāo),后續(xù)會(huì)結(jié)合具體的例子進(jìn)一步闡述。
EXPLAIN 語(yǔ)法
EXPLAIN 用于查看 SQL 語(yǔ)句的執(zhí)行計(jì)劃,語(yǔ)法如下:
EXPLAIN explainable_stmtexplainable_stmt: {SELECT statement| DELETE statement| INSERT statement| REPLACE statement| UPDATE statement }操作符介紹
本小節(jié)詳細(xì)介紹 DRDS 執(zhí)行計(jì)劃中各個(gè)操作符的含義。
LogicalView
LogicalView 是從底層數(shù)據(jù)源獲取數(shù)據(jù)的操作符。從數(shù)據(jù)庫(kù)的角度來(lái)看,使用?TableScan?命名更符合常規(guī),但考慮到 DRDS 本身不存儲(chǔ)數(shù)據(jù),而是通過(guò) SQL 從底層數(shù)據(jù)源獲取,因此,該操作符中會(huì)記錄下推的 SQL 語(yǔ)句和數(shù)據(jù)源信息,這更像一個(gè) "視圖"。該 "視圖" 中的 SQL,通過(guò)優(yōu)化器的下推,可能包含多種操作,如投影、過(guò)濾、聚合、排序、連接和子查詢等。
以下通過(guò)示例說(shuō)明 EXPLAIN 中 LogicalView 的輸出信息及其含義:
mysql> explain select * From sbtest1 where id > 1000; +-----------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +-----------------------------------------------------------------------------------------------------------------------+ | UnionAll(concurrent=true) | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)") | | HitCache:false ? ? | +-----------------------------------------------------------------------------------------------------------------------+ 3 rows in set (0.00 sec)LogicalView 的信息由三部分構(gòu)成:
- tables:底層數(shù)據(jù)源對(duì)應(yīng)的表名,以?.?分割,其前是分庫(kù)對(duì)應(yīng)的編號(hào),其后是表名及其編號(hào),對(duì)于連續(xù)的編號(hào),會(huì)做簡(jiǎn)寫(xiě),如?[000-127],表示表名編號(hào)從?000?到?127?的所有表。
- shardCount:需要訪問(wèn)的分表總數(shù),該示例中會(huì)訪問(wèn)從?000?到?127?共 128 張分表。
- sql:下發(fā)至底層數(shù)據(jù)源的 SQL 模版。這里顯示的并非真正下發(fā)的 SQL 語(yǔ)句,DRDS 在執(zhí)行時(shí)會(huì)將表名替換為物理表名;另外,SQL 中的常量?10?被???替換,這是因?yàn)?DRDS 默認(rèn)開(kāi)啟了 PlanCache 功能,對(duì) SQL 做了參數(shù)化處理。
UnionAll
UnionAll 是?UNION ALL?對(duì)應(yīng)的操作符,該操作符通常有多個(gè)輸入,表示將多個(gè)輸入的數(shù)據(jù) UNION 在一起。以上示例中,LogicalView 之上的 UnionAll 表示將所有分表中的數(shù)據(jù)進(jìn)行 UNION。
UnionAll 中的?concurrent?表示是否并行執(zhí)行其子操作符,默認(rèn)為 true。
UnionDistinct
與 UnionAll 類似,UnionDistinct 是?UNION DISTINCT?對(duì)應(yīng)的操作符。如下:
mysql> explain select * From sbtest1 where id > 1000 union distinct select * From sbtest1 where id < 200; +-------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +-------------------------------------------------------------------------------------------------------------------------+ | UnionDistinct(concurrent=true) | | UnionAll(concurrent=true) | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)") | | UnionAll(concurrent=true) | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` < ?)") | | HitCache:false | +-------------------------------------------------------------------------------------------------------------------------+ 6 rows in set (0.02 sec)MergeSort
MergeSort,歸并排序操作符,通常有多個(gè)子操作符。DRDS 中實(shí)現(xiàn)了兩種排序:基于有序數(shù)據(jù)的歸并排序和對(duì)無(wú)序數(shù)據(jù)的內(nèi)存排序。如下:
mysql> explain select *from sbtest1 where id > 1000 order by id limit 5,10; +---------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +---------------------------------------------------------------------------------------------------------------------------------------------------+ | MergeSort(sort="id ASC", offset=?1, fetch=?2) | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?) ORDER BY `id` LIMIT (? + ?)") | | HitCache:false | +---------------------------------------------------------------------------------------------------------------------------------------------------+ 3 rows in set (0.00 sec)MergeSort 操作符包含三部分內(nèi)容:
- sort:表示排序字段以及排列順序,id ASC?表示按照?id?字段遞增排序,DESC?表示遞減排序。
- offset:表示獲取結(jié)果集時(shí)的偏移量,同樣由于對(duì) SQL 做了參數(shù)化,示例中的?offst?表示為??1?,其中???表示這是一個(gè)動(dòng)態(tài)參數(shù),其后的數(shù)字對(duì)應(yīng)參數(shù)列表的下標(biāo)。示例中 SQL 對(duì)應(yīng)的參數(shù)為?[1000, 5, 10],因此,?1?實(shí)際對(duì)應(yīng)的值為?5。
- fetch:表示最多返回的數(shù)據(jù)行數(shù)。與?offset?類似,同樣是參數(shù)化的表示,實(shí)際對(duì)應(yīng)的值為?10。
Aggregate
Aggregate 是聚合操作符,通常包含兩部分內(nèi)容:Group By 字段和聚合函數(shù)。如下:
mysql> explain select k, count(*) from sbtest1 where id > 1000 group by k; +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Aggregate(group="k", count(*)="SUM(count(*))") | | MergeSort(sort="k ASC") | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT `k`, COUNT(*) AS `count(*)` FROM `sbtest1` WHERE (`id` > ?) GROUP BY `k` ORDER BY `k`") | | HitCache:true | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 4 rows in set (0.00 sec)Aggregate 包含兩部分內(nèi)容:
- group:表示 GROUP BY 字段,示例中為?k?。
- 聚合函數(shù):=?前為聚合函數(shù)對(duì)應(yīng)的輸出列名,其后為對(duì)應(yīng)的計(jì)算方法。示例中?count(*)="SUM(count(*))"?,第一個(gè)?count(*)?對(duì)應(yīng)輸出的列名,隨后的?SUM(count(*))?表示對(duì)其輸入數(shù)據(jù)中的?count(*)?列進(jìn)行?SUM?運(yùn)算得到最終的?count(*)。
由此可見(jiàn),DRDS 將聚合操作分為兩部分,首先將聚合操作下推至底層數(shù)據(jù)源做局部聚合,最終在 DRDS 層面對(duì)局部聚合的結(jié)果做全局聚合。另外,DRDS 的最終聚合是基于排序做的,因此,會(huì)在優(yōu)化器階段為其添加一個(gè)?Sort?子操作符,而?Sort?操作符又進(jìn)一步通過(guò)下推 Sort 轉(zhuǎn)換為?MergeSort。
再來(lái)看一個(gè)?AVG?聚合函數(shù)的例子,如下:
mysql> explain select k, avg(id) avg_id from sbtest1 where id > 1000 group by k; +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN| +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Project(k="k", avg_id="sum_pushed_sum / sum_pushed_count")| | Aggregate(group="k", sum_pushed_sum="SUM(pushed_sum)", sum_pushed_count="SUM(pushed_count)")| | MergeSort(sort="k ASC")| | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT `k`, SUM(`id`) AS `pushed_sum`, COUNT(`id`) AS `pushed_count` FROM `sbtest1` WHERE (`id` > ?) GROUP BY `k` ORDER BY `k`")| | HitCache:false| +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 5 rows in set (0.01 sec)DRDS 會(huì)將?AVG?聚合函數(shù)轉(zhuǎn)換為?SUM / COUNT,再分別根據(jù)?SUM?和?COUNT?的下推規(guī)則,將其轉(zhuǎn)換為局部聚合和全局聚合。用戶可自行嘗試了解其他聚合函數(shù)的執(zhí)行計(jì)劃。
注意:DRDS 會(huì)將?DISTINCT?操作轉(zhuǎn)換為?GROUP?操作,如下:
mysql> explain select distinct k from sbtest1 where id > 1000; +-----------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +-----------------------------------------------------------------------------------------------------------------------------------------------------+ | Aggregate(group="k") | | MergeSort(sort="k ASC") | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT `k` FROM `sbtest1` WHERE (`id` > ?) GROUP BY `k` ORDER BY `k`") | | HitCache:false | +-----------------------------------------------------------------------------------------------------------------------------------------------------+ 4 rows in set (0.02 sec)TmpSort
TmpSort,表示在內(nèi)存中對(duì)數(shù)據(jù)進(jìn)行排序。與 MergeSort 的區(qū)別在于,MergeSort 可以有多個(gè)子操作符,且每個(gè)子操作符返回的數(shù)據(jù)都已經(jīng)排序。TmpSort 僅有一個(gè)子操作符。
TmpSort 對(duì)應(yīng)的查詢計(jì)劃信息與 MergeSort 一致,請(qǐng)參考 MergeSort。
Project
Project 表示投影操作,即從輸入數(shù)據(jù)中選擇部分列輸出,或者對(duì)某些列進(jìn)行轉(zhuǎn)換(通過(guò)函數(shù)或者表達(dá)式計(jì)算)后輸出,當(dāng)然,也可以包含常量。以上?AVG?的示例中,最頂層就是一個(gè)?Project,其輸出?k?和?sum_pushed_sum / sum_pushed_count?,后者對(duì)應(yīng)的列名為?avg_id?。
mysql> explain select '你好, DRDS', 1 / 2, CURTIME(); +-------------------------------------------------------------------------------------+ | LOGICAL PLAN | +-------------------------------------------------------------------------------------+ | Project(你好, DRDS="_UTF-16'你好, DRDS'", 1 / 2="1 / 2", CURTIME()="CURTIME()") | | | | HitCache:false | +-------------------------------------------------------------------------------------+ 3 rows in set (0.00 sec)可見(jiàn),Project 的計(jì)劃中包括每列的列名及其對(duì)應(yīng)的列、值、函數(shù)或者表達(dá)式。
Filter
Filter 表示過(guò)濾操作,其中包含一些過(guò)濾條件。該操作符對(duì)輸入數(shù)據(jù)進(jìn)行過(guò)濾,若滿足條件,則輸出,否則丟棄。如下是一個(gè)較復(fù)雜的例子,包含了以上介紹的大部分操作符。
mysql> explain select k, avg(id) avg_id from sbtest1 where id > 1000 group by k having avg_id > 1300; +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Filter(condition="avg_id > ?1") | | Project(k="k", avg_id="sum_pushed_sum / sum_pushed_count") | | Aggregate(group="k", sum_pushed_sum="SUM(pushed_sum)", sum_pushed_count="SUM(pushed_count)") | | MergeSort(sort="k ASC") | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT `k`, SUM(`id`) AS `pushed_sum`, COUNT(`id`) AS `pushed_count` FROM `sbtest1` WHERE (`id` > ?) GROUP BY `k` ORDER BY `k`") | | HitCache:false | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 6 rows in set (0.01 sec)在以上?AVG?示例的 SQL 基礎(chǔ)上添加了having avg_id > 1300?,執(zhí)行計(jì)劃最上層添加了一個(gè) Filter 操作符,用于過(guò)濾所有滿足?avg_id > 1300?的數(shù)據(jù)。
有讀者可能會(huì)問(wèn),WHERE 中的條件為什么沒(méi)有對(duì)應(yīng)的 Filter 操作符呢?在 DRDS 優(yōu)化器的某個(gè)階段,WHERE 條件的 Filter 操作符的確是存在的,只是最終將其下推到了 LogiacalView 中,因此可以在 LogicalView 的?sql?中看到?id > 1000?。
NlJoin
NlJoin,表示 NestLoop Join 操作符,即使用 NestLoop 方法進(jìn)行兩表 Join。DRDS 中實(shí)現(xiàn)了兩種 JOIN 策略:NlJoin 和 BKAJoin,后者表示 Batched Key Access Join,批量鍵值查詢,會(huì)從左表取一批數(shù)據(jù),構(gòu)建一個(gè) IN 條件拼接在訪問(wèn)右表的 SQL 中,從右表一次獲取一批數(shù)據(jù)。
mysql> explain select a.* from sbtest1 a, sbtest1 b where a.id = b.k and a.id > 1000; +----------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +----------------------------------------------------------------------------------------------------------------------------+ | Project(id="id", k="k", c="c", pad="pad") | | NlJoin(id="id", k="k", c="c", pad="pad", k0="k0", condition="id = k", type="inner") | | UnionAll(concurrent=true) | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)") | | UnionAll(concurrent=true) | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT `k` FROM `sbtest1` WHERE (`k` > ?)") | | HitCache:false | +----------------------------------------------------------------------------------------------------------------------------+ 7 rows in set (0.03 sec)NlJOIN 的計(jì)劃包括三部分內(nèi)容:
- 輸出列信息:輸出的列名,示例中的 JOIN 會(huì)輸出 5 列?id="id", k="k", c="c", pad="pad", k0="k0"?。
- contition:連接條件,示例中連接條件為?id = k?。
- type:連接類型,示例中是 INNER JOIN,因此其連接類型為?inner?。
BKAJoin
BKAJoin,Batched Key Access Join,表示通過(guò)批量鍵值查詢的方式進(jìn)行 JOIN,即從左表取一批數(shù)據(jù),構(gòu)建一個(gè) IN 條件拼接在訪問(wèn)右表的 SQL 中,從右表一次獲取一批數(shù)據(jù)進(jìn)行 JOIN。
mysql> explain select a.* from sbtest1 a, sbtest1 b where a.id = b.k order by a.id; +-------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +-------------------------------------------------------------------------------------------------------------------------------+ | Project(id="id", k="k", c="c", pad="pad") | | BKAJoin(id="id", k="k", c="c", pad="pad", id0="id0", k0="k0", c0="c0", pad0="pad0", condition="id = k", type="inner") | | MergeSort(sort="id ASC") | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` ORDER BY `id`") | | UnionAll(concurrent=true) | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`k` IN ('?'))") | | HitCache:false | +-------------------------------------------------------------------------------------------------------------------------------+ 7 rows in set (0.01 sec)BKAJoin 的計(jì)劃內(nèi)容與 NlJoin 相同,這兩個(gè)操作符命名不同,旨在告知執(zhí)行器以何種方法執(zhí)行 JOIN 操作。另外,以上執(zhí)行計(jì)劃中右表的 LogicalView 中?k IN ('?')?是優(yōu)化器構(gòu)建出來(lái)的對(duì)右表的IN查詢模板。
LogicalModifyView
如上文介紹,LogicalView 表示從底層數(shù)據(jù)源獲取數(shù)據(jù)的操作符,與之對(duì)應(yīng)的,LogicalModifyView 表示對(duì)底層數(shù)據(jù)源的修改操作符,其中也會(huì)記錄一個(gè) SQL 語(yǔ)句,該 SQL 可能是 INSERT、UPDATE 或者 DELETE。
mysql> explain update sbtest1 set c='Hello, DRDS' where id > 1000; +--------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +--------------------------------------------------------------------------------------------------------------------------------+ | LogicalModifyView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="UPDATE `sbtest1` SET `c` = ? WHERE (`id` > ?)") | | HitCache:false | +--------------------------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.03 sec)mysql> explain delete from sbtest1 where id > 1000; +-------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +-------------------------------------------------------------------------------------------------------------------------+ | LogicalModifyView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="DELETE FROM `sbtest1` WHERE (`id` > ?)") | | HitCache:false | +-------------------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.03 sec)LogicalModifyView 查詢計(jì)劃的內(nèi)容與 LogicalView 類似,包括下發(fā)的物理分表,分表數(shù)以及 SQL 模版。同樣,由于開(kāi)啟了 PlanCache,對(duì) SQL 做了參數(shù)化處理,SQL 模版中的常量會(huì)用???替換。
PhyTableOperation
PhyTableOperation 表示對(duì)某個(gè)物理分表執(zhí)行一個(gè)操作。該操作符目前僅用于 INSERT INTO ... VALUES ...。
mysql> explain insert into sbtest1 values(1, 1, '1', '1'),(2, 2, '2', '2'); +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | PhyTableOperation(tables="SYSBENCH_CORONADB_1526954857179TGMMSYSBENCH_CORONADB_VGOC_0000_RDS.[sbtest1_001]", sql="INSERT INTO ? (`id`, `k`, `c`, `pad`) VALUES(?, ?, ?, ?)", params="`sbtest1_001`,1,1,1,1") | | PhyTableOperation(tables="SYSBENCH_CORONADB_1526954857179TGMMSYSBENCH_CORONADB_VGOC_0000_RDS.[sbtest1_002]", sql="INSERT INTO ? (`id`, `k`, `c`, `pad`) VALUES(?, ?, ?, ?)", params="`sbtest1_002`,2,2,2,2") | | | | HitCache:false | +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 4 rows in set (0.00 sec)示例中,INSERT 插入兩行數(shù)據(jù),每行數(shù)據(jù)對(duì)應(yīng)一個(gè) PhyTableOperation 操作符,PhyTableOperation 操作符的內(nèi)容包括三部分:
- tables:物理表名,僅有唯一一個(gè)物理表名。
- sql:SQL 模版,該 SQL 模版中表名和常量均被參數(shù)化,用???替換,對(duì)應(yīng)的參數(shù)在隨后的 params 中給出。
- params:SQL 模版對(duì)應(yīng)的參數(shù),包括表名和常量。
其他信息
HitCache
DRDS 會(huì)默認(rèn)開(kāi)啟 PlanCache 功能,HitCache 用于告知用戶當(dāng)前查詢是否命中 PlanCache。如下,第一次運(yùn)行 HitCache 為 false,第二次運(yùn)行為 true。
mysql> explain select * From sbtest1 where id > 1000; +-----------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +-----------------------------------------------------------------------------------------------------------------------+ | UnionAll(concurrent=true) | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)") | | HitCache:false ? ? | +-----------------------------------------------------------------------------------------------------------------------+ 3 rows in set (0.01 sec)mysql> explain select * From sbtest1 where id > 1000; +-----------------------------------------------------------------------------------------------------------------------+ | LOGICAL PLAN | +-----------------------------------------------------------------------------------------------------------------------+ | UnionAll(concurrent=true) | | LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)") | | HitCache:true | +-----------------------------------------------------------------------------------------------------------------------+ 3 rows in set (0.00 sec)小結(jié)
以上介紹了 DRDS 5.3 的 EXPLAIN 命令,以及執(zhí)行計(jì)劃中每個(gè)操作符的含義,相信可以為用戶調(diào)優(yōu) SQL 提供極大得便利。
DRDS 5.3 已經(jīng)在阿里云正式上線,除全新設(shè)計(jì)的執(zhí)行計(jì)劃外,性能也有大幅提升,并支持原生事務(wù)、Outline 和 Plan Cache 等功能。后續(xù)支持復(fù)雜查詢的只讀實(shí)例、回收站、基于事務(wù)的廣播表寫(xiě)入等功能也將相繼上線,敬請(qǐng)期待。
?原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的DRDS分布式SQL引擎—执行计划介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Mac 神兵利器(二) 极简软件清单
- 下一篇: PostgreSQL Oracle 兼容