zoukankan      html  css  js  c++  java
  • Oracle学习笔记之八(几条简明的优化SQL方法)

    1. 常规SQL语句优化

    1.1 建议不用“*”来代替所有列名

    SELECT语句中可以用“*“来列出某个表的所有列名,但是这样的写法对Oracle系统来说会存在解析的动态问题。Oracle系统会通过查询数据字典来将”*“转换成表的所有列      名,这自然会消耗系统时间。

    1.2 用TRUNCATE代替DELETE  

    当使用DELETE删除表中的数据行时,Oracle会使用撤消表空间(UNDO tablespace)来存放恢复信息。而TRUNCATE则不会。语法:

    truncate [table|cluster] schema.[tale_name][cluster_name][drop|reuse storage]

    创建一存储过程,实现使用truncate命令动态删除数据表:

    create or replace procedure trun_table(table_deleted in varchar2) as --实现清空指定的表的存储过程
        cur_name integer;  --存储打开的游标
    begin
        cur_name := dbms_sql.open_cursor;  --打开游标
        dbms_sql.parse(cur_name,'truncate table '||table_deleted||' drop storage',
            dbms_sql.native);  --执行truncate table table_deleted命令
        dbms_sql.close_cursor(cur_name); --关闭游标
    exception
        when others then
            dbms_sql.close_cursor(cur_name); --异常时...
        raise;
    end trun_table;
    /

    1.3 在确保完整性的情况下多用COMMIT语句

    在PL/SQL块中,经常将几个相互联系的DML语句写在一个BEGIN...END块中,建议在每个块的END前面使用COMMIT语句,这样就可以实现对象DML语句的及时提交,同时也释放事务所占用的资源。

    1.4 尽量减少表的查询次数

    在含有子查询的SQL语句中,要特别注意减少对表的查询。 

    1.5 用[NOT] EXISTS代替[NOT] IN

    在子查询中,[NOT] IN子句将执行一个内部的排序与合并,无论在哪种买号上,[NOT] IN都是最低效的,因为它对子查询中的表执行了一个全表遍历。为了避免使用[NOT] IN,我们可以把它改成外连接(outer joins)、[NOT] EXISTS子句,如下面的两段代码:

    第一种,低效率的NOT IN子句:

    select empno,ename from emp
        where empno not in(select deptno from dept where loc='BEIJING');

    第二种,高效率的EXIST子句:

    select empno,ename from emp
        where exists(select deptno from dept where loc='BEIJING');

    当[NOT] IN后面跟子查询,并且查询的结果集较多时,不宜使用[NOT] IN;但如果[NOT] IN后面的括号内是列表(可枚举的几个)或子查询所满足结果集较少时,也是可以使用的。 

    2. 表连接优化

    2.1 驱动表的选择

    驱动表(Driving Table)是指被最先访问的表(通常以全表扫描的方式被访问)。示范:

    select s.name,d.dept_name from department d,students s
        where d.dept_no=s.dept_no;

    假设在STUDENTS表的DEPT_NO列创建了索引,而在DEPARTMENT表的DEPT_NO列没有索引。由于DEPARTMENT最先被访问(紧随FROM其后),这样DEPARTMENT表将被作为查询中的驱动表。需要对两张表都建立索引,否则影响效率。

    2.2 WHERE子句的连接顺序

    Oracle采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可买过滤些最大数据记录的条件必须写的WHERE子句的末尾,也就是在表进行连接操作以前,过滤掉的记录数据越多越好。

    3. 合理使用索引

    3.1 索引列和表达式的选择

    • 对于取值较少的关键字或表达式,不要采用标准的B树索引,可以考虑建立位图索引。
    • 不要将那些频繁修改的列作为索引列。
    • 在选择索引列时,还要考虑该索引所引起的INSERT、UPDATE、DELETE操作是否值得。

    3.2 使用复合索引

    create index complex_index on tb_test(column1,column2,column3);

     这里的索引是一个复合索引,它包含三列,在查询语句中要带有WHERE...AND从句才能使用该复合索引。

    3.3 避免全表扫描大表

    以下情况下Oracle会使用全表扫描:

    • 所查询的表没有索引;
    • 需要返回所有的行;
    • 带like并使用”%“这样的语句就是全表扫描;
    • 对索引主列有条件限制,但使用了函数,则Oracle使用全表扫描;
    • 带有is null、is not null或!=等字句也导致全表扫描。比如:
      select * from emp where job != 'MANAGER';
  • 相关阅读:
    Shiro【常用的自定义】
    Shiro【重要概念总结】
    Shiro【自定义Realm实战】
    Shiro【内置Realm实操】
    Shiro【快速上手】
    Shiro【初识】
    面向对象【抽象类和接口的区别】
    面向对象【多态中的成员访问特点】
    Kafka2.12-2.5.0在windows环境的安装 启动 通信测试
    CentOS.iso 下载地址收纳整理
  • 原文地址:https://www.cnblogs.com/nayitian/p/3228854.html
Copyright © 2011-2022 走看看