本文仅介绍各类数据库执行计划的获取方式,执行计划内容的解读请参照官方文档
创建示例表 test,对应 DDL 语句如下
1
| SQL> create table test (id int primary key, name varchar(20))
|
PostgreSQL/Kingbase(人大金仓)
1
| SQL> explain [(format [json|yaml|text])] select * from test
|
format
参数是可选的,但是格式化之后的数据可以方便通过代码读取- 支持的 SQL 类型 SELECT,INSERT,UPDATE,DELETE,VALUES,EXECUTE,DECLARE,CREATE TABLE,CREATE MATERIALIZED VIEW
不添加 format
参数的结果
1
| Seq Scan on test (cost=0.00..22.70 rows=1270 width=36)
|
添加 format json
的结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| [
{
"Plan": {
"Node Type": "Seq Scan",
"Parallel Aware": false,
"Relation Name": "test",
"Alias": "test",
"Startup Cost": 0.00,
"Total Cost": 22.70,
"Plan Rows": 1270,
"Plan Width": 36
}
}
]
|
MySQL
1
| SQL> explain select * from test
|
- 支持的 SQL 类型:SELECT,DELETE,INSERT,REPLACE,UPDATE

Oracle
1
2
3
4
5
| SQL> delete from plan_table where statement_id = '{statement_id}'
SQL> explain plan set statement_id = '{statement_id}' for select * from test
SQL> select id,lpad(' ',depth*2,' ')||operation || ' ' || options PLAN_STEP,OBJECT_OWNER,OBJECT_NAME,OBJECT_TYPE,COST,CARDINALITY,ACCESS_PREDICATES,FILTER_PREDICATES from plan_table where statement_id = '{statement_id}' order by id";
|
- 在执行之前需要先从表执行计划的表中删除指定
{statement_id}
的数据 {statement_id}
是执行计划表中一次执行计划的唯一标识- 支持的 SQL 类型:INSERT,UPDATE,DELETE,SELECT

DB2
1
| SQL> explain plan set QUERYTAG='{statement_id}' for select * from test
|
- DB2 需要先设置解释 schema
{explain_schema}
之后才能获取对应的执行计划数据 {statement_id}
是执行计划表中一次执行计划的唯一标识- DB2 的执行结果需要结合多张解释表综合读取,此处就不做展示了
- 支持的 SQL 类型:SELECT,MERGE,TRUNCATE,INSERT,UPDATE,DELETE
SQL Server
1
2
3
| SQL> set showplan_all on
SQL> select * from test
SQL> set showplan_all off
|
- SQL Server 提供了三种类型的参数来获取执行计划
showplan_all/showplan_xml/showplan_text
showplan_xml/showplan_text
是以文本的形式展示执行计划showplan_all
则是以结果集的形式展示执行计划
- 位于
set showplan_all on
与 set showplan_all off
之间的语句并不会实际执行,所以在开启 showplan
参数之后记得关掉它,否则在当前会话执行的所有 SQL 都不会实际去执行
showplan_all 结果展示

showplan_xml 结果展示
1
| <ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.0" Build="9.00.1399.06"><BatchSequence><Batch><Statements><StmtSimple StatementText="select * from test" StatementId="1" StatementCompId="1" StatementType="SELECT" StatementSubTreeCost="0.0409839" StatementEstRows="10032" StatementOptmLevel="TRIVIAL"><StatementSetOptions QUOTED_IDENTIFIER="false" ARITHABORT="false" CONCAT_NULL_YIELDS_NULL="false" ANSI_NULLS="false" ANSI_PADDING="false" ANSI_WARNINGS="false" NUMERIC_ROUNDABORT="false"/><QueryPlan CachedPlanSize="9"><RelOp NodeId="0" PhysicalOp="Table Scan" LogicalOp="Table Scan" EstimateRows="10032" EstimateIO="0.0298702" EstimateCPU="0.0111137" AvgRowSize="11" EstimatedTotalSubtreeCost="0.0409839" Parallel="0" EstimateRebinds="0" EstimateRewinds="0"><OutputList><ColumnReference Database="[master]" Schema="[dbo]" Table="[test]" Column="id"/></OutputList><TableScan Ordered="0" ForcedIndex="0" NoExpandHint="0"><DefinedValues><DefinedValue><ColumnReference Database="[master]" Schema="[dbo]" Table="[test]" Column="id"/></DefinedValue></DefinedValues><Object Database="[master]" Schema="[dbo]" Table="[test]"/></TableScan></RelOp></QueryPlan></StmtSimple></Statements></Batch></BatchSequence></ShowPlanXML>
|
DM(达梦)
1
| SQL> explain for select * from test
|

1
| echo -e "SET EXPLAIN FILE TO '"'{temp_file}'"';\n SET EXPLAIN ON AVOID_EXECUTE;\n select * from test1\n "| dbaccess sysmaster
|
- Informix 的执行计划是通过终端命令而非 SQL 指令来获取的
{temp_file}
指定的是执行计划的输出文件,若该文件不存在,Informix 会自动创建- 支持审核的 SQL 类型:SELECT,MERGE,INSERT,UPDATE,DELETE