- 前言
- 格式
- Text/String
- XML
- JSON
- DOT
- 属性级别
我们知道Calcite会将SQL为RelNode构成的执行计划,为了分析执行计划,经常会使用RelOptUtil.toString()将其转为字符串。其实,除了这种字符串之外还有更多的格式,可以展示执行计划:XML、JSON、DOT。
格式在SqlExplainFormat中可以看到这四种格式,其中TEXT其实和String一样
在RelOptUtilTest.java中构建一个单测,利用已有的relBuilder可以快速构建一个RelNode
RelNode aggregate = relBuilder.scan("DEPT")
.aggregate(relBuilder.groupKey(),
relBuilder.aggregateCall(SqlStdOperatorTable.COUNT))
.limit(0, 10)
.build();
Text/String
String strPlan = RelOptUtil.toString(aggregate);
System.out.println(strPlan);
String textPlan = RelOptUtil.dumpPlan("TEXT:",
aggregate,
SqlExplainFormat.TEXT,
SqlExplainLevel.ALL_ATTRIBUTES);
System.out.println(textPlan);
打印的结果有些差别,是因为SqlExplainLevel.ALL_ATTRIBUTES选择的是所有属性;toString只是EXPPLAN_ATTRIBUTES级别
LogicalSort(fetch=[10])
LogicalAggregate(group=[{}], agg#0=[COUNT()])
LogicalTableScan(table=[[scott, DEPT]])
TEXT:
LogicalSort(fetch=[10]): rowcount = 1.0, cumulative cost = {6.125 rows, 21.0 cpu, 0.0 io}, id = 4
LogicalAggregate(group=[{}], agg#0=[COUNT()]): rowcount = 1.0, cumulative cost = {5.125 rows, 5.0 cpu, 0.0 io}, id = 3
LogicalTableScan(table=[[scott, DEPT]]): rowcount = 4.0, cumulative cost = {4.0 rows, 5.0 cpu, 0.0 io}, id = 2
XML
String xmlPlan = RelOptUtil.dumpPlan("xml:",
aggregate,
SqlExplainFormat.XML,
SqlExplainLevel.ALL_ATTRIBUTES);
System.out.println(xmlPlan);
XML格式的,直观上看起来还不如Text了
JSON10 {} COUNT() [scott, DEPT]
String jsonPlan = RelOptUtil.dumpPlan("json:",
aggregate,
SqlExplainFormat.JSON,
SqlExplainLevel.ALL_ATTRIBUTES);
System.out.println(jsonPlan);
看起来也不是很方便,但是json格式便于传输
{
"rels": [
{
"id": "0",
"relOp": "LogicalTableScan",
"table": [
"scott",
"DEPT"
],
"inputs": []
},
{
"id": "1",
"relOp": "LogicalAggregate",
"group": [],
"aggs": [
{
"agg": {
"name": "COUNT",
"kind": "COUNT",
"syntax": "FUNCTION_STAR"
},
"type": {
"type": "BIGINT",
"nullable": false
},
"distinct": false,
"operands": [],
"name": null
}
]
},
{
"id": "2",
"relOp": "LogicalSort",
"collation": [],
"fetch": {
"literal": 10,
"type": {
"type": "INTEGER",
"nullable": false
}
}
}
]
}
DOT
String dotPlan = RelOptUtil.dumpPlan("dot:",
aggregate,
SqlExplainFormat.DOT,
SqlExplainLevel.ALL_ATTRIBUTES);
System.out.println(dotPlan);
这个主要是用于绘图,而不是直接观察计划
digraph {
"LogicalAggregatengroup = {}nagg#0 = COUNT()nrowcount = 1.0 cumulnative cost = {5.125 nrows, 5.0 cpu, 0.0 ino} id = 3" -> "LogicalSortnfetch = 10nrowcount = 1.0 cumulnative cost = {6.125 nrows, 21.0 cpu, 0.0 nio} id = 4" [label="0"]
"LogicalTableScanntable = [scott, DEPTn]nrowcount = 4.0 cumulnative cost = {4.0 ronws, 5.0 cpu, 0.0 io}n id = 2" -> "LogicalAggregatengroup = {}nagg#0 = COUNT()nrowcount = 1.0 cumulnative cost = {5.125 nrows, 5.0 cpu, 0.0 ino} id = 3" [label="0"]
}
将plan保存plan.dot文件,然后使用graphviz的命令dot -Tsvg -o plan.svg plan.dot生成svg图片
也可以通过-T指定其他格式,如-Tpng
用浏览器可以直接打开生成的svg图
刚刚提到SqlExplainLevel导致了TEXT和String的不一样,其实一共有5种级别
用上文的RelNode感受一下,这些plan的不同吧
noAttributes:
LogicalSort
LogicalAggregate
LogicalTableScan
expPlanAttributes:
LogicalSort(fetch=[10])
LogicalAggregate(group=[{}], agg#0=[COUNT()])
LogicalTableScan(table=[[scott, DEPT]])
digestAttributes:
LogicalSort(fetch=[10])
LogicalAggregate(group=[{}], agg#0=[COUNT()])
LogicalTableScan(table=[[scott, DEPT]])
nonCostAttributes:
LogicalSort(fetch=[10]), id = 4
LogicalAggregate(group=[{}], agg#0=[COUNT()]), id = 3
LogicalTableScan(table=[[scott, DEPT]]), id = 2
allAttributes:
LogicalSort(fetch=[10]): rowcount = 1.0, cumulative cost = {6.125 rows, 21.0 cpu, 0.0 io}, id = 4
LogicalAggregate(group=[{}], agg#0=[COUNT()]): rowcount = 1.0, cumulative cost = {5.125 rows, 5.0 cpu, 0.0 io}, id = 3
LogicalTableScan(table=[[scott, DEPT]]): rowcount = 4.0, cumulative cost = {4.0 rows, 5.0 cpu, 0.0 io}, id = 2



