zoukankan      html  css  js  c++  java
  • sql语句优化

    1.sql语句关键字用大写的。因为oracle总是先解析sql语句,把小写的字母转换成大写的再执行

    2.查询子句中避免使用 ‘ * ‘,在解析的过程中, 会将'*' 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间。

    3.减少访问数据库的次数,每次访问,数据库内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等

    4.用索引提高效率。

    ORACLE使用了一个复杂的自平衡B-tree结构. 通常,通过索引查询数据比全表扫描要快,当ORACLE找出执行查询和Update语句的最佳路径时, ORACLE优化器将使用索引。
    同样在联结多个表时使用索引也可以提高效率。
    另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证。那些LONG或LONG RAW数据类型, 可以索引几乎所有的列。
    注意到索引的代价:
    索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改。
    这意味着每条记录的INSERT , DELETE , UPDATE将为此多付出4 , 5 次的磁盘I/O 。
    因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。定期的重构索引是有必要的!ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
    另外,如果检索数据量超过30%的表中记录数.使用索引将没有显著的效率提高。

    5.避免在索引列上使用NOT。
    通常,我们要避免在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的影响. 当ORACLE”遇到”NOT,他就会停止使用索引转而执行全表扫描。

    6.避免在索引列上使用计算。
    WHERE子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描。举例:
    低效:
    SELECT … FROM DEPT WHERE SAL * 12 > 25000;
    高效:
    SELECT … FROM DEPT WHERE SAL > 25000/12;

    7.避免在索引列上使用IS NULL和IS NOT NULL。
    避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引,对于单列索引,如果列包含空值,索引中将不存在此记录;
    对于复合索引,如果每个列都为空,索引中同样不存在此记录。如果至少有一个列不为空,则记录存在于索引中。
    举例: 如果唯一性索引建立在表的A列和B列上, 并且表中存在一条记录的A,B值为(123,null) , ORACLE将不接受下一条具有相同A,B值(123,null)的记录(插入),然而如果所有的索引列都为空,ORACLE将认为整个键值为空而空不等于空. 因此你可以插入1000 条具有相同键值的记录,当然它们都是空! 因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使ORACLE停用该索引。
    低效: (索引失效)
    SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL;
    高效: (索引有效)
    SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;

    8.用>=替代>
    高效:
    SELECT * FROM EMP WHERE DEPTNO >=4
    低效:
    SELECT * FROM EMP WHERE DEPTNO >3
    两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录。

    9.通过内部函数提高SQL效率。
    复杂的SQL往往牺牲了执行效率. 能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的。

    10.整合简单,无关联的数据库访问,如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)。
    使用表的别名(Alias):当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。

    11.尽量多使用COMMIT, 这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少。
    COMMIT所释放的资源:
    a. 回滚段上用于恢复数据的信息.
    b. 被程序语句获得的锁
    c. redo log buffer 中的空间
    d. 数据库为管理上述3种资源中的内部花费。
    用TRUNCATE替代DELETE。用truncate清除数据,内存中表空间中其被删除数据的表占用的空间会被立即释放。

    12.用Where子句替换HAVING子句。
    在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤,然后再计算,计算完后再由having进行过滤。

    13.用EXISTS替换DISTINCT。
    当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT,一般可以考虑用EXIST替换, EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果. 例子:
    (低效):
    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);

    14.选择最有效率的表名顺序(只在基于规则的优化器中有效):
    ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,
    在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.

    15.WHERE子句中的连接顺序.:
    ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。

  • 相关阅读:
    bzoj1037: [ZJOI2008]生日聚会Party(DP)
    bzoj1034: [ZJOI2008]泡泡堂BNB(贪心)
    bzoj1025: [SCOI2009]游戏(数学 + 思维 + DP)
    第十章、嵌入式Linux的调试技术 读书笔记
    第九章、硬件抽象层:HAL 读书笔记
    第八章 让开发板发出声音:蜂鸣器驱动
    ANDROID深度探索(卷1)HAL与驱动开发 第七章
    ANDROID深度探索(卷1)HAL与驱动开发 第六章
    ANDROID深度探索(卷1)HAL与驱动开发 第五章
    ANDROID深度探索(卷1)HAL与驱动开发 第四章
  • 原文地址:https://www.cnblogs.com/cashew/p/10722259.html
Copyright © 2011-2022 走看看