您的位置:首页 > 数据库

使用解释工具分析SQL语句

2013-04-25 19:04 134 查看

我当前的环境为AIX6.1+DB2 9.7。



数据库在执行一条SQL之前,首先要准备SQL语句。在准备过程中,SQL语句被简化为代数语句(DB2 优化器(Optimizer)随后对此代数语句进行优化,这个”代数语句“即“查询图解模型”)。DB2优化器会分析该SQL语句,并生成访问计划,访问计划包含将用于执行该语句的策略的详细信息(如索引,排序等)。如果SQL语句实在应用程序中编写的,那么其访问计划生成于预编译时,另外还会生成一个可执行形式的访问计划,它作为称为“包”的对象存储在系统目录中。对于在CLP中提交或是应用程序中的动态语句,那么访问计划将在该语句发出时生成,也会生成可执行形式的访问计划并且存储于内存中(全局包缓冲区)而非系统目录。

要对一条SQL进行分析,必须捕获并查看存储于SQL语句中的访问计划,而为此目的,必须使用DB2解释工具。

解释工具可以帮助我们捕获并查看SQL语句的访问计划,帮助确定编写不良的语句或数据库中弱点的性能信息;另外还能帮助我们了解DBM如何为满足查询而访问的表和索引;还能帮助我们评判性能调忧行动,在我们更改DBM,DB的参数,或调整SQL语句前后都检查解释数据,以此查看调整的效果。

使用数据库解释工具分两个阶段,一个是解释数据收集阶段,另外一个阶段是查询前阶段所收集到的信息。

收集解释数据的可行方法包括:

执行 EXPLAIN SQL 语句
设置 CURRENT EXPLAIN MODE 特殊寄存器
设置 CURRENT EXPLAIN SNAPSHOT 特殊寄存器
在 PRECOMPILE 或 BIND 命令中使用 EXPLAIN 绑定选项
在 PRECOMPILE 或 BIND 命令中使用 EXPLSNAP 绑定选项

所收集的解释数据分两类:

全面解释数据(Comprehensive explain data)。包含关于一条 SQL 语句的访问计划的详细信息。此信息跨多个不同的解释表存储。
解释快照数据(Explain snapshot data)。包含一条 SQL 语句的当前内部表示以及所有相关信息。此信息存储在 EXPLAIN_STATEMENT 解释表的 SNAPSHOT 列中。

查看解释数据的方法:

db2expln
db2exfmt
Visual Explain

从上图也可以看出,db2expln工具直接处理包而非全面解释数据或解释快照数据,所以获取包的访问计划。但由于 db2expln 工具仅可访问已存储在包中的信息,因而只能说明所选的最终访问计划的实现,不能提供特定 SQL 语句优化方式的信息。

db2exfmt 工具设计用于直接处理已收集并存储在解释表中的全面解释数据或解释快照数据。

Visual Explain 是一种 GUI 工具,并且只能查看解释快照数据。

要查看已收集并写入了解释表的全面解释数据,则必须使用 db2exfmt 工具

总结一下:常用的方法是使用EXPLAIN SQL 语句收集解释数据,然后使用db2exfmt工具来查询解释数据。

创建解释表:

在捕获解释信息之前首先要创建解释表(Visual Explain工具运行时会自动创建解释表)。而由于解释表常用于开发阶段,所以解释表不会在数据库初始化的时候自动创建。在需要时,用户需要手动创建解释表。

创建解释表的方法有两种:

1.调用 SYSPROC.SYSINSTALLOBJECTS存储过程

$db2 CONNECT TO database-name$db2 CALL SYSPROC.SYSINSTALLOBJECTS('EXPLAIN', 'C',CAST (NULL AS VARCHAR(128)),

>CAST (NULL AS VARCHAR(128)))

所有的解释表将创建在SYSTOOLS模式下,如果要在其他模式中创建解释表,那么修改最后一个参数为目标模式名称。

2.使用EXPLAIN.DDL脚本(脚本位置:INSTHOME/sqllib/misc)

$db2 CONNECT TO database-name$db2 -tf
EXPLAIN.DDL

此脚本将在当前模式下创建解释表。

解释工具在收集解释数据的时候会按照一定的顺序寻找解释表,找到后开始插入解释数据:

1.对于动态SQL:在session authorization ID对应的模式下寻找解释表

2.对于静态SQL:在statement authorization ID对应的模式下寻找解释表

注:相应的模式下会关联一组解释表,或者是只想其他模式中解释表的别名。如果在相应的模式下没找到任何解释表,那么将在

SYSTOOLS模式下寻找解释表。Explain工具在向解释表中插入数据的时候不会激活触发器,约束检查或外键检查。

使用EXPLAIN语句收集解释数据:

EXPLAIN语句捕获“可解释的语句”的访问计划信息并将其插入解释表。

所谓可解释的语句(即可以捕获访问计划的SQL)包括:CALL, Compound SQL (Dynamic), DELETE, INSERT,

MERGE, REFRESH, SELECT,SELECT INTO, SET INTEGRITY, UPDATE, VALUES, or VALUES INTO,

或者是一个有效的XQuery语句。

语法:

>>-EXPLAIN--+-PLAN SELECTION-+--+--------------------+----------> +-ALL------------+ '-+-FOR--+--SNAPSHOT-' | (1) | '-WITH-' '-PLAN-----------' >--+-----------------+--+------------------------+--------------> '-WITH
REOPT ONCE-' '-SET QUERYNO = -integer-' >--+---------------------------------+--------------------------> '-SET QUERYTAG = -string-constant-' >--FOR--+-explainable-sql-statement--------------+-------------><
'-XQUERY--'explainable-xquery-statement'-'

说明:

PLAN SELECTION指示将查询编译的计划选择阶段的信息插入解释表;

ALL和PLAN都与PLAN SELECTION作用相同,其中PLAN是用于系统语法兼容性而设置的。所以一般指定ALL即可。

FOR SNAPSHOT只有快照信息收集到EXPLAIN_STATEMENT表的SNAPSHOT字段中;

WITH SNAPSHOT指示收集全面解释数据和快照数据;

DEFAULT(不指定FOR SNAPSHOT或WITH SNAPSHOT选项)只收集全面解释数据,不收集快照数据;

WITH OPT ONCE 有待了解。。。

SET QUERYNO =integer 其中integer必须为正数,作为查询语句的一个标记(tag)记录在EXPLAIN_STATEMENT表

的QUERYNO字段中。默认情况下,动态语句为1,静态语句由与编译器指定;

SET QUERYTAG=string-constant 长度为20字节字符串的一个查询语句标记(tag)记录在EXPLAIN_STATEMENT表

的QUERYTAG字段中。默认为空;

FOR explainable-sql-statement要查询的语句

FOR XQUERY 有待了解。。。

我是在toad中运行的explain all for SQL;

在CLP中运行explain是要注意,如果之间在命令行中输入$explain all for SQL将提示”Phrase?“,此时调用的是UNIX的

explain,需要输入db2 “explain all for SQL”;

关于解释数据的清除:可以看下所有EXPLAIN表的定义,不难发现EXPLAIN_INSTANCE是主表,其他表或者与他有外键关系,或者间接与它有外键约束关系,都定义了ON DELETE CASCADE语句,所以如果我们删除了EXPLAIN_INSTANCE表中的记录,那么其他EXPLAIN表也同时被清空。

使用db2expln描述访问计划:

db2expln工具是用于查询未收集解释数据的SQL的访问计划,即可以不收集解释数据而查看访问计划。 对于静态SQL和

XQUERY语句,db2expln描述存储在系统目录中的packages中的SQL语句的访问计划;对于动态SQL和XQUERY 语句,db2expln查询存储在内存(cache section)中的信息。

具体用法这里不说了,除了看信息中心外,还可以在OS中输入db2expln查看帮助,很详细。

创建一个stmt.db2文件,然后把SQL语句写入其中,SQL语句以@结束(以;结束貌似有问题)。然后输入命令:

$db2expln -database cphapp -stmtfile stmt.db2 -terminator @ -terminal

说明:-stmtfile指定SQL所在文件;-terminator @指定SQL语句以@符号结束;-terminal指将输出传至标准输出。

使用db2exfmt描述访问计划:

db2exfmt工具使用来格式化解释表(Explain tables)中的内容,给定数据库名和其他的信息,工具将查询解释表并且

格式化并输出结果。

查看信息中心或输入db2exfmt -h可以得到相关帮助信息。

$db2exfnt -d cphapp -e SYSTOOS -n SYSSH200 -o db2exfmt.rpt

说明:注意,首先要用EXPLAIN语句收集解释信息,然后才能用此工具格式化并输出解释结果。

-d 指出要连接的数据库为cphapp;-e 指出解释表所属模式;-n指出要解析的查询名称为SYSSH200(可以从

SYSTOOLS.EXPLAIN_STATEMENT表中得到;-o 指出要将结果输出到文件db2exfmt.rpt中;另外回车后还会提示要求

输入timestamp,试了一下EXPLAIN_STATEMENT表中的EXPLAIN_TIME,结果提示找不到,默认为-1,也就是最近的

查询信息,所以用默认值即可;另外SOURCE_SCHEMA也可以默认;Section number我也用默认,OK,收庄稼吧!

也可以使用:db2exfmt -d sample -edcompher -n % -w -1 -s % -# 0 –o
db2exfmt.rpt

输出所有解释表中的信息(-n %)



文章转载于:http://www.db2china.net/home/space.php?uid=29548&do=blog&id=14170
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: