本文仅介绍各类数据库执行计划的获取方式,执行计划内容的解读请参照官方文档

创建示例表 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

Imgur

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

Imgur

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 onset showplan_all off 之间的语句并不会实际执行,所以在开启 showplan 参数之后记得关掉它,否则在当前会话执行的所有 SQL 都不会实际去执行

showplan_all 结果展示

Imgur

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

Imgur

Informix

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