转载请注明原地址,谢谢
(一)MySQL explain用法
explain table_name 或 explain [extended] select select_options
前者可以得出一个表的字段结构等,后者提供MySQL如何执行SQL语句的一些信息。
Explain可以用在select,delete,insert,replace和update之前。
Explain输出的列信息
id |
Select查询的id |
select_type |
select查询的类型,主要是区别普通查询和联合查询、子查询之类的复杂查询。 |
table |
输出的行所引用的表 |
type |
Join的类型 |
possible_key |
MySQL能使用哪个索引在该表中找到行 |
key |
显示MySQL实际决定使用的索引。如果没有索引被选择,键是NULL。 |
key_len |
所选键的长度 |
ref |
显示哪个字段与索引一起被使用 |
rows |
估计要遍历多少条数据 |
extra |
额外的信息 |
这是在MySQL中实测的结果,在将近两千万的数据量上执行explain语句,耗时低于10毫秒。
(二)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 PLAN的SET STATEMENT_ID子句提供的SQL语句的唯一标志符。 |
PLAN_ID |
NUMBER |
执行计划的在全局表plan_table中的唯一标识符 |
TIMESTAMP |
DATE |
EXPLAN PLAN语句执行的日期和时间 |
REMARKS |
VARCHAR2(80) |
注释 |
OPERATION |
VARCHAR2(30) |
执行的操作类型。如TABLE ACCESS,SORT或HASH JOIN |
OPTIONS |
VARCHAR2(225) |
操作的附加信息,例如,以TABLE SCAN为例,选项可能是FULL或BY 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_START和PARTITION_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, JSON或YAML。非文本的输出包含文本输出格式相同的信息,但是更容易被程序解析。这个参数缺省为TEXT。
例子:
(四)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语句查询。
PostgreSQL同MySQL一样也是直接在语句前使用explain,返回结果是文本。
DB2比较麻烦,需要进行一些设置,其结果存在特定的文件中。
以上四种数据库中,除MySQL外,其他三种数据库的执行计划信息中都包含cost信息。