• Oracle SQL优化


    Oracle SQL优化

    数据访问数据方式


      1.全表扫描


      2.索引扫描 : index --> rowID -- >数据


      (1) 扫描索引得到对应的rowid值。 --可能从内存中得到


      (2) 通过找到的rowid从表中读出具体的数据。--物理IO,消耗也大

        索引唯一扫描(index unique scan) :返回单个ROWID,如:存在UNIQUE 或PRIMARY KEY 约束
        索引范围扫描(index range scan) :通常是组合索引,返回多行数据
        索引全扫描(index full scan) :只返回索引列时
        索引快速扫描(index fast full scan) :只返回索引列时,不对数据排序-不带order by情况下常发生


      3.rowId(包括索引):包括where中有rowID 及 索引方式

    SQL调优使用技巧

      ★索引要定期维护,定期重建


      ★索引上不用NOT、IS NULL和IS NOT NULL:用了将进行全表扫描


      ★避免使用前置通配符:LIKE '%109204421' 通配符在前面不走索引


      ★索引列是函数不走索引,如 businessNo * 12 >500


      ★将*转换成具体的列名称


      ★用EXISTS替换DISTINCT
      例如:

      低效:
        SELECT DISTINCT DEPT_NO,DEPT_NAME
        FROM DEPT D,EMP E
        WHERE D.DEPT_NO = E.DEPT_NO

      高效:
        SELECT DEPT_NO,DEPT_NAME
        FROM DEPT D
        WHERE EXISTS ( SELECT ‘X’
        FROM EMP E
        WHERE E.DEPT_NO = D.DEPT_NO);


      ★UNION-ALL 代替 UNION


      ★索引有多个列中,只有第一个列在Where中才会用到索引。


      ★避免出现索引列自动转换:内部发生的类型转换, 这个索引将不会被用到。
        如 WHERE USER_NO = 109204421,USER_NO为字符串,
        那么会自动转换成number来比较,这样就不走索引了。


      ★在查询时尽量少用格式转换:
        如用:WHERE a.order_no = b.order_no
        不用:WHERE TO_NUMBER (substr(a.order_no, instr(b.order_no, '.') - 1) = TO_NUMBER (substr(a.order_no, instr(b.order_no, '.') - 1)


      ★减少对表的查询
      例如:
        低效
        SELECT TAB_NAME
        FROM TABLES
        WHERE TAB_NAME = ( SELECT TAB_NAME FROM TAB_COLUMNS WHERE VERSION = 604)

        AND DB_VER= ( SELECT DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)
      高效
        SELECT TAB_NAME
        FROM TABLES
        WHERE (TAB_NAME,DB_VER)= ( SELECT TAB_NAME,DB_VER) FROM TAB_COLUMNS WHERE VERSION = 604)

      ★尽可能使用NOT EXISTS来代替NOT IN

      ★用>= 替代 >


      ★外部联接"+"的用法 :
        外部联接"+"按其在"="的左边或右边分左联接和右联接。
        若不带"+"运算符的表中的一个行不直接匹配于带"+"预算符的表中的任何行,
        则前者的行与后者中的一个空行相匹配并被返回。
        利用外部联接"+",可以替代效率十分低下的 not in 运算,大大提高运行速度。
        例如,下面这条命令执行起来很慢:
        select a.empno from emp a where a.empno not in (select empno from emp1 where job='SALE');

        利用外部联接,改写命令如下:

        select a.empno from emp a ,emp1 b
        where a.empno=b.empno(+)
        and b.empno is null and b.job='SALE';

  • 相关阅读:
    设计模式 ( 十七) 状态模式State(对象行为型)
    设计模式 ( 十六 ) 观察者模式Observer(对象行为型)
    设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)
    设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)
    设计模式 ( 十三 ) 命令模式Command(对象行为型)
    设计模式(十一)代理模式Proxy(结构型)
    设计模式(十)享元模式Flyweight(结构型)
    开源项目
    C#中的Marshal
    给枚举加上Description,必要时,可以直接获取枚举类型代表的中文
  • 原文地址:https://www.cnblogs.com/caoshouling/p/8644853.html
Copyright © 2020-2023  润新知