前面介绍了一些 SQL*PLUS 知识, 我已经知道, 注意: autotrace 只能运行在SQL*PLUS上, 在 toad 上运行, 实际底层也是运行在 sql*plus 上.
autotrace 显示计划很容易, 但是, 它很容易遗漏一些重要信息, 例如 分区信息, 绑定变量 等.
而直接使用命令 explain 可以不遗漏分区信息, 运行办法是:
explain plan for select … (注意, 这样只是临时显示, 如果你想保存这个计划, 那么需要 加上一个id, 一般不需要保存这个计划)
explain plan 与 autotrace 是亲亲关系, 大师使用 autotrace 作为头等调整工具, 所以, 个人还是推荐使用 autotrace, 放弃 explain, 大不了使用 10046.
在sql*plus 与在 toad 中运行的结果, execution plan 略有不同, 其中 sql*plus 会有如下内容:
(Cost=24 Card=155 Bytes=17205)
Cost: 为每一步查询的成本
Card: 基数的缩写(Cardinality), 它是特定查询计划不周将输出的记录的行数的估计.
Bytes: CBO预测每一个计划步骤将返回的数据字节数量. 依据是: 基数(Card) 和 行宽.
另外: statistics 显示的内容中:
recursive calls : 为执行你的SQL语句所运行的SQL语句的数目
递归调用统计数据是指由于你需要执行其他SQL语句而必须执行的SQL. 例如, 如果你执行了一个插入语句, 它触发了一个运行某查询的触发器, 它就是递归SQL.
递归调用的原因:
1) 硬解析, select * from scott.emp; 查询计划中看到很多递归调用, 但是第2次执行的时候就没有了, 这是因为第1次是硬解析, 注意: 虽然语句上我们只是一条SQL语句, 但是, 系统内部, oracle 可以需要查询很多系统的东西, 比如权限之类的.
2) PL/SQL函数调用, 如果一个SQL语句调用了一个PL/SQL函数, 而这个PL/SQL函数本身又需要运行很多SQL, 那么就会又很高的递归调用. 貌似这种的话, 用包就好好一些.
递归调用小结: 记住, 递归SQL只要可能就要避免.
检索的数据块 = db blocks gets(从data buffer中读取) + consistent gets(从undo buffer中读取)
通常, 减少数据块读取 和 一致读取的主要方法是通过查询调整, 但是, 要想成功, 必须保持开放的思路并对可行的访问路径有很好的了解.
需要多少实际I/O或物理I/O的一个度量, 表或索引数据的一个物理读取把某块放入缓冲区高速缓存中, 然后我们执行一个逻辑I/O检索该块. 因此, 大多数物理读取的后面都直接跟着一个逻辑I/O.
重做尺寸统计信息显示在执行过程中产生了多少重做数据. 在鉴别大批量操作时, 它是最有用的.
具体查看我的 blog, 读 10046 tkprof.
参考我的blog 读statspack 干货