本章提要
------------------------------------------------------
调优技术及什么时候使用
------------------------------------------------------
绝对有必要问自己如下三个问题:
~ 这条SQL语句是已知并且确定不变的么?
~ 即将采用的措施会影响到单个会话(甚至整个系统)的某一条SQL语句还是全部SQL语句?
~ 有可能改变这条SQL语句么?
7.1 改变访问结构
SQL语句的响应时间往往不仅取决于这些数据是如何存储的, 而且也取决于这些数据是如何访问的.
当你质疑目前的SQL语句时, 首先需要做的是检查当前的访问结构, 从数据字典获得信息, 回答以下问题:
~ 语句中涉及的表的结构类型是什么? 堆表, 索引组织表, 还是外部表? 以及表是否存储在聚簇中?
~ 包含所需数据的物化视图可用么?
~ 在表, 聚簇和物化视图中存在哪些索引? 这些索引建立在哪些字段上, 这些字段的顺序又如何?
~ 所有这些数据段(表,索引等逻辑存储结构)是如何被分区的?
当你要改变访问结构时, 最重要的是仔细考虑可能的副作用.
7.2 修改SQL语句
SQL 常常可以通过不同的方法提交一个完全相同的请求. 举例:
/* 以下4个查询, 返回的结果集是一样的, 但是它们的执行计划是不一样的 SQL 可以通过很多不同的方法返回一样的结果集 哪种是最好的方法呢? 是开发者要考虑的 */ SELECT deptno FROM dept WHERE deptno NOT IN (SELECT deptno FROM emp); SELECT deptno FROM dept WHERE NOT EXISTS (SELECT 1 FROM emp WHERE emp.deptno = dept.deptno) SELECT deptno FROM dept MINUS SELECT deptno FROM emp SELECT dept.deptno FROM dept, emp WHERE dept.deptno = emp.deptno(+) AND emp.deptno IS NULL
7.3 提示
指定提示, 你的目标是减少查询优化器要评估的执行计划的数据.
~ 提示必须紧跟着 delete, insert, merge, update 关键字.
~ 在注释分隔符之后的第一个字符必须是加号(+)
提示的分类: 很多, 具体参考 oracle的 sql reference, 11g以后可以通过 v$sql_hint 视图来查询
提示的有效域: 提示仅仅对单个查询块起作用. 例如:
-- 两个查询块分别指定了提示 WITH emps AS (SELECT /*+ full(emp) */ deptno, count(*) AS cnt FROM emp GROUP BY deptno) SELECT /*+ full(dept) */ dept.dname, emps.cnt FROM dept, emps WHERE dept.deptno = emps.deptno
等等吧, 个人感觉提示在测试的时候使用较多, 真正开发时, 感觉不怎么使用提示, 所以这部分没有完成, 需要的时候再补充吧.
另外, 提示只是给查询优化器做一个参考, 查询优化器也未必一定就使用提示.
7.4 改变执行环境
要修改很多参数, 个人感觉默认的就可以, 再确认吧
7.5 SQL概要
图形化界别的东西, 但是感觉好像是收费之类, 目前先跳过
总结一下, 目前我能用的是, 改变访问结构, 修改SQL语句, 使用提示来测试, 只有这些.