MySQL,Oracle,DB2,PostgreSQL上explain的用法

时间:2024-03-14 07:46:02

转载请注明原地址,谢谢


(一)MySQL explain用法

 

explain table_name explain [extended] select select_options

前者可以得出一个表的字段结构等,后者提供MySQL如何执行SQL语句的一些信息。

Explain可以用在selectdeleteinsertreplaceupdate之前。

 

Explain输出的列信息

id

Select查询的id

select_type

select查询的类型,主要是区别普通查询和联合查询、子查询之类的复杂查询。

table

输出的行所引用的表

type

Join的类型

possible_key

MySQL能使用哪个索引在该表中找到行

key

显示MySQL实际决定使用的索引。如果没有索引被选择,键是NULL

key_len

所选键的长度

ref

显示哪个字段与索引一起被使用

rows

估计要遍历多少条数据

extra

额外的信息

 

这是在MySQL中实测的结果,在将近两千万的数据量上执行explain语句,耗时低于10毫秒。

 MySQL,Oracle,DB2,PostgreSQL上explain的用法

(二)Oracle explain plan用法

 

EXPLAIN PLAN

   [ SET STATEMENT_ID = string ]

   [ INTO [schema.] table_name [@dblink] ]

FOR SQL_STATEMENT ;

 

EXPLAIN PLAN的相关选项如下:

l     STATEMENT_ID

    SQL语句的唯一标识符。通过使用SQL语句的标识符,可以向一个计划表中存入多条SQL语句。

l     TABLE_NAME

    存储执行计划的计划表的名称。此表必须已经存在并且与标准表结构一致。如果没有指定计划表名称,EXPLAIN PLAN会尝试使用表名PLAN_TABLE.

l     SQL_STATEMENT

    你想要知道其执行计划的那条SQL语句。这条SQL语句必须是有效的。并且你也必须有足够的权限来执行它。这条SQL语句可以含有绑定变量。

 

默认情况下,Oracle会将执行计划插入如到一张名为PLAN_TABLE的表中。可以使用脚本utlexplain.sql来创建自己的计划表。这个脚本位于Oracle软件安装目录的子目录$ORACLE_HMOE/rmdbs/admin/中。从Oracle 10g开始,Oracle会创建一个全局临时表PLAN_TABLE供所有用户使用,所以通常情况下不需要创建自己的计划表。由于此默认的计划表是一个全局临时表,所以你无法看到其他会话插入的执行计划,你的执行计划也会随着自己会话的结束而自动消失。

 

PLAN_TABLE表信息

 

列名

类型

描述

STATEMENT_ID

VARCHAR2(30)

EXPLAIN PLANSET STATEMENT_ID子句提供的SQL语句的唯一标志符。

PLAN_ID

NUMBER

执行计划的在全局表plan_table中的唯一标识符

TIMESTAMP

DATE

EXPLAN PLAN语句执行的日期和时间

REMARKS

VARCHAR2(80)

注释

OPERATION

VARCHAR2(30)

执行的操作类型。如TABLE ACCESS,SORTHASH JOIN

OPTIONS

VARCHAR2(225)

操作的附加信息,例如,以TABLE SCAN为例,选项可能是FULLBY ROWID

OBJECT_NODE

VARCHAR2(128)

如果是分布式查询,这一列表示用于引用对象的数据库链接名称。如果并行查询,它的值可能对应一个临时的结果集。

OBJECT_NAME

VARCHAR2(30)

对象名称

OBJECT_ALIAS

VARCHAR2(65)

对象的别名

OBJECT_INSTANCE

NUMERIC

对象在SQL语句中的位置

OBJECT_TYPE

VARCHAR2(30)

对象的类型(表,索引等)

OPTIMIZER

VARCHAR2(255)

解释SQL语句时生效的优化器

ID

NUMERIC

执行计划的ID

PARENT_ID

NUMERIC

上一个步骤的ID

DEPTH

NUMERIC

操作的深度

POSITION

NUMERIC

如果两个步骤有相同的父步骤,有更低POSITION值的步骤将被先执行

COST

NUMERIC

优化器估算出来的此操作的相对成本

CARDINALITY

NUMERIC

优化器预期这一步将返回的记录数

BYTES

NUMERIC

预计这一步将返回的字节数

OTHER_TAG

VARCHAR2(255)

标识OTHER列中的值的类型。

PARTITION_START

VARCHAR2(255)

访问的分区范围的起始分区

PARTITION_STOP

VARCHAR2(255)

访问的分区范围的结束分区

PARTITION_ID

NUMERIC

计算PARTITION_STARTPARTITION_STOP列的值对的ID

OTHER

LONG

对于分布式查询,这列可能是包含发往远程数据库的SQL语句的文本。对于并行查询,它比啊是并行从属进程执行的SQL语句。

DISTRIBUTION

VARCHAR2(30)

描述记录是如何从一组并行查询从属进程分配到后续的“消费者”从属进程的。

CPU_COST

NUMERIC

估算出来的操作的CPU成本

IO_COST

NUMERIC

估算出来的的操作的IO成本

TEMP_SPACE

NUMERIC

估算出来的这一步操作所使用的临时存储的空间大小

ACCESS_PREDICATES

VARCHAR2(4000)

SQL语句中,确定如何在当前步骤中提取记录的子句。

FILTER_PREDICATES

VARCHAR2(4000)

SQL语句中确定对见记录进行过滤的子句路,如WHERE子句在非索引列上的条件。

PROJECTION

VARCHAR2(4000)

决定将返回的记录的子句,通常是SELECT后面的字段列表

TIME

NUMBER(20,2)

优化器为这一步执行估算的时间消耗

QBLOCK_NAME

VARCHAR2(30)

查询块的唯一标识符。

 

查看执行计划

有两种方法可以查看执行计划:直接查看计划表(SQL语句)和DBMS_XPLAN.DISPALY表函数。

第二种例子

SQL> select * from table(dbms_xplan.display());

 

 

(三)PostgreSQL explain用法

 

EXPLAIN [ ( option [, ...] ) ] statement

EXPLAIN [ ANALYZE ] [ VERBOSE ] statement

 

option有以下几种

 

    ANALYZE [ boolean ]

    VERBOSE [ boolean ]

    COSTS [ boolean ]

    BUFFERS [ boolean ]

    TIMING [ boolean ]

FORMAT { TEXT | XML | JSON | YAML }

 

各参数含义

ANALYZE:执行语句并显示真正的运行时间和其它统计信息,默认值False。注意:ANALYZE会真正执行SQL语句。

VERBOSE:显示额外的信息,尤其是计划树中每个节点的字段列表,schema识别表和函数名称。总是打印统计数据中显示的每个触发器的名字。这个参数缺省为FALSE

COSTS:包括每个计划节点的启动成本预估和总成本的消耗,也包括行数和行宽度的预估。这个参数缺省为TRUE

BUFFERS:包含Buffer使用信息。特别包括共享块命中、读、脏和写的次数,本地块命中、读、脏和写,临时块读和写的次数。命中意味着避免了物理读,因为块在需要时已经在缓存中发现了。共享块包含普通表和索引的数据;本地块包含临时表和索引的数据;而临时块包含用于排序、哈希、物化计划节点和类似情况的短期工作数据。脏块的数量表示该查询之前改变且未提交的块的数量;写块的数量表示在查询时被后台进程从缓存释放的脏块数量。上层节点显示的块的数量是所有它的子节点使用块的数量合计。在文本格式中只打印非零值。该参数可能只在ANALYZE也启用的时候使用。它的缺省为FALSE

TIMING:在输出中包含实际启动时间和每个节点花费的时间。重复读系统块在某些系统上会显著的减缓查询的速度,所以当需要只统计实际行数且没有准确时间时,该参数设置为FALSE会很有用。即使节点级别时间统计被关闭,整个语句的运行时间也是要被计量的。

这个参数可能只在ANALYZE也启用的时候使用。缺省为TRUE

FORMAT:声明输出格式,可以为TEXT, XML, JSONYAML。非文本的输出包含文本输出格式相同的信息,但是更容易被程序解析。这个参数缺省为TEXT

 

例子:

 MySQL,Oracle,DB2,PostgreSQL上explain的用法

 

(四)DB2 explain用法

 

DB2中查看执行计划比较麻烦,以下是查看步骤:

1. DB2中,我们必须首先创建一组特殊的表(解释表)之后才能捕获解释信息。

db2 -tvf $HOME/sqllib/misc/EXPLAIN.DDL

2. 设置成解释模式,并不真正执行下面将发出的sql命令

db2 set current explain mode explain

3. 执行sql语句

例子:db2 “select * from user”

4.取消解释模式

db2 set current explain mode no

5.执行计划输出到文件db2exmt.out

db2exfmt -d sample -g TIC -w -l -s % -n % -o db2exmt.out

 

db2exmt.out文件中包含cost信息。


db2还有一种方法可以查看执行计划相关信息。首先创建explain表:
$ db2 -tvf $HOME/sqllib/misc/EXPLAIN.DDL

然后在你想查看的SQL语句前面加上explain plan for

例如:explain plan for select * for test

此时并不会想MySQL一样直接显示相关信息。执行计划相关信息在EXPLAIN_STATEMENT中

执行SQL语句 select * for EXPLAIN_STATEMENT 就可以查看执行计划相关信息

 

 

总结:MySQL直接在语句前使用explain,返回结果是同select查询一样的结果集。

Oracle是直接在语句前使用explain plan for(当然其中还可以设置许多参数),不返回结果,执行计划信息存在特定的表中,可通过SQL语句查询。

PostgreSQLMySQL一样也是直接在语句前使用explain,返回结果是文本。

DB2比较麻烦,需要进行一些设置,其结果存在特定的文件中。

 

以上四种数据库中,除MySQL外,其他三种数据库的执行计划信息中都包含cost信息。