天天看点

Oracle智能之SQL诊断:SQL Tuning Advisor推荐执行计划

编辑手记:在前一段,一篇智能数据库优化的论文引起广泛的关注,其实在 oracle 数据库中,已经引入了大量自动化和智能化的方法去进行自动调节,包括在 sql 层面的智能诊断分析和建议。

Oracle智能之SQL诊断:SQL Tuning Advisor推荐执行计划
张大朋(lunar)oracle 资深技术专家 lunar 拥有超过十年的 oracle support 从业经验,曾经服务于oracle acs部门,现就职于 oracle sales consultant 部门,负责的产品主要是 exadata,golden gate,database 等。

本文的测试目的,起因一个问题:当有hint时,并且hint跟需要绑定的执行计划有冲突,谁的优先级高?

在这个演示过程中,使用sql tuning advisor来进行辅助,在 oracle 数据库中,sql tuning advisor 的智能化程度可能超过很多人的想象,应该多学习和使用。

首先创建一个测试用例:

lunar@lunardb>create table lunartest1 (n number ); table created. elapsed: 00:00:00.08 lunar@lunardb>begin   2         for i in 1 .. 10000 loop   3             insert into lunartest1 values(i);   4             commit;   5         end loop;   6        end;   7  / pl/sql procedure successfully completed. lunar@lunardb>create index idx_lunartest1_n on lunartest1(n); index created. elapsed: 00:00:00.04

执行查询,我们看到sql按照hint的方式没有使用索引,而是全表扫描,这是我们预期的结果:

Oracle智能之SQL诊断:SQL Tuning Advisor推荐执行计划

下面我们运行sql tuning advisor来生成建议报告:

Oracle智能之SQL诊断:SQL Tuning Advisor推荐执行计划

查看生成的报告内容:

Oracle智能之SQL诊断:SQL Tuning Advisor推荐执行计划
Oracle智能之SQL诊断:SQL Tuning Advisor推荐执行计划
Oracle智能之SQL诊断:SQL Tuning Advisor推荐执行计划

这里我们看到sql tuning advisor提示了两个建议:

<code>1.收集统计信息</code><code>:</code>

<code>execute dbms_stats.gather_table_stats(ownname =&gt;</code><code>'lunar'</code><code>,</code>

<code>tabname =&gt;</code><code>'lunartest1'</code><code>,</code>

<code>estimate_percent =&gt; dbms_stats.auto_sample_size,</code>

<code>method_opt =&gt;</code><code>'for all columns size auto'</code><code>);</code>

<code>2,提供了一个执行计划建议:</code><code></code>

<code>execute dbms_sqltune.accept_sql_profile(task_name =&gt;</code>

<code>'lunar_tunning_bjgduva68mbqm'</code><code>,</code>

<code>task_owner =&gt;</code><code>'lunar'</code><code>,</code>

<code>replace =&gt;</code><code>true);</code>

并且给出了这个执行计划和原始执行计划的对比,可以看到 执行效率提高了89%以上,逻辑读从23降低为2,减少了91.3%。

我们按照建议执行以上的两条命令。首先收集统计信息,再接受建议的执行计划,现在看看 sql 执行的情况:

Oracle智能之SQL诊断:SQL Tuning Advisor推荐执行计划

这里我们看到,这个执行计划中已经使用了索引,并且逻辑读从49降低为14。

现在我们查看一下这个sql profile的outline:

Oracle智能之SQL诊断:SQL Tuning Advisor推荐执行计划

这里我们看到该sqp profile中提供了详细的表和列的统计信息

并且有“ignore_optim_embedded_hints”,也就是忽略嵌入到sql中的hint 。

结论:虽然这个sql的hint中指定了no index,即不使用索引,但是sql语句仍然按照sys_sqlprof_015236655fb80000指定的profile使用了index。

 这说明dbms_sqltune.accept_sql_profile方式绑定的执行计划优先级高于hint指定是否使用索引的方式。