博客
关于我
SQL优化34条
阅读量:389 次
发布时间:2019-03-04

本文共 2886 字,大约阅读时间需要 9 分钟。

ORACLE SQL 优化技巧指南

在数据库管理中,ORACLE SQL的性能优化至关重要。以下是一些实用的技巧,帮助您提升查询效率并减少资源消耗。

  • 表名顺序优化

    ORACLE解析器从右到左处理FROM子句中的表名。在多个表连接查询时,应选择记录条数最少的表作为基础表。如果有超过三个表的连接查询,则需要选择交叉表作为基础表,交叉表是被其他表引用的表。

  • WHERE子句处理顺序

    ORACLE自下而上解析WHERE子句。WHERE子句中的条件应按从上到下的顺序排列,能够过滤最大数量记录的条件应放在子句末尾,以减少不必要的计算。

  • 避免使用“*”

    ORACLE会将“*”逐个转换为所有列名,导致更多时间用于数据字典查询。建议直接指定所需列名以提高效率。

  • 减少数据库访问次数

    ORACLE内部执行多项任务,如解析SQL、估算索引利用率、绑定变量等。定期使用COMMIT命令可以释放资源,减少锁和回滚段的负担。

  • 重新设置ARRAYSIZE参数

    在SQLPlus、SQLForms和Pro*C中,建议将ARRAYSIZE参数设置为200,这样可以一次检索更多数据,提高访问效率。

  • 使用DECODE函数

    DECODE函数可以避免重复扫描相同记录或重复连接表,减少处理时间。

  • 整合简单的数据库访问

    将多个简单查询整合为一个查询,即使它们之间没有关联,也能减少总体资源消耗。

  • 删除重复记录

    使用ROWID的方法删除重复记录,例如:

  • DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
    1. 使用TRUNCATE替代DELETE

      TRUNCATE命令可以避免回滚段存放可恢复信息,适用于删除表中全部记录。

    2. 尽量多使用COMMIT

      在程序中使用尽可能多的COMMIT,可以释放资源并减少锁的竞争。

    3. 用WHERE替代HAVING

      HAVING子句在查询结果后进行过滤,而WHERE子句可以在结果计算前过滤记录,提高效率。

    4. 减少对表的查询

      在含有子查询的SQL中,减少对表的查询次数。例如:

    5. SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME, DB_VERSION) = (SELECT TAB_NAME, DB_VERSION FROM TAB_COLUMNS WHERE VERSION = 604);
      1. 使用内部函数提高效率

        复杂的SQL查询往往牺牲了执行效率,但掌握运用函数解决问题的方法在实际工作中非常有意义。

      2. 使用表别名

        在连接多个表时,使用表别名并在列名前加上别名,减少解析时间并减少歧义。

      3. 用EXISTS替代IN

        EXISTS和NOT EXISTS比IN更高效,因为它们不需要对子查询中的表执行全表遍历。

      4. 识别低效执行的SQL语句

        虽然有许多工具可用于SQL优化,但手动编写工具并监控执行情况也是有效的方法。以下是一个示例查询,用于监控执行情况:

      5. SELECT EXECUTIONS, DISK_READS, BUFFER_GETS, 
        ROUND((BUFFER_GETS - DISK_READS)/BUFFER_GETS, 2) Hit_ratio,
        ROUND(DISK_READS/EXECUTIONS, 2) Reads_per_run,
        SQL_TEXT
        FROM V$SQLAREA
        WHERE EXECUTIONS > 0 AND BUFFER_GETS > 0
        AND (BUFFER_GETS - DISK_READS)/BUFFER_GETS < 0.8
        ORDER BY 4 DESC;
        1. 使用索引提高效率
          索引可以显著提高查询效率,但也需要注意索引的维护和管理。ORACLE使用自平衡B-tree结构,通常比全表扫描快。
        2. ALTER INDEX 
          REBUILD
          ;
          1. 用EXISTS替代DISTINCT
            在部门和雇员表的查询中,使用EXISTS替代DISTINCT可以提高效率。例如:
            低效
          2. 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 E.DEPT_NO FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
            1. 使用大写字符

              ORACLE解析SQL语句时会将小写字母转换为大写,因此建议在编写SQL时使用大写字母。

            2. 避免在索引列上使用NOT

              在索引列上使用NOT会导致ORACLE停止使用索引,改用全表扫描。

            3. 避免在索引列上使用计算

              WHERE子句中如果索引列是函数的一部分,优化器将不使用索引。

            4. 用>=替代>

              例如:
              低效

            5. SELECT * FROM EMP WHERE DEPTNO > 3;

              高效

              SELECT * FROM EMP WHERE DEPTNO >= 4;
              1. 用UNION-ALL替代UNION
                UNION-ALL可以减少排序操作,提高效率。例如:
                低效
              2. SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95' UNION SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95';

                高效

                SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95' UNION-ALL SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95';
                1. 用WHERE替代ORDER BY
                  在满足WHERE子句条件时,索引效率更高。例如:
                  低效
                2. SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE;

                  高效

                  SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0;
                  1. 避免改变索引列的类型

                    确保索引列的类型不会发生改变,避免类型转换影响索引使用。

                  2. 避免在索引列上使用IS NULL和IS NOT NULL

                    索引列中不能有空值,否则索引无法有效使用。

                  3. 总是使用索引的第一列

                    如果索引是多列索引,优化器会优先使用索引的第一列。

                  4. 通过遵循以上优化技巧,您可以显著提升ORACLE SQL的执行效率,减少资源消耗并提高用户满意度。

    转载地址:http://upje.baihongyu.com/

    你可能感兴趣的文章
    iOS_Runtime3_动态添加方法
    查看>>
    我用wxPython搭建GUI量化系统之最小架构的运行
    查看>>
    selenium+python之切换窗口
    查看>>
    Find Familiar Service Features in Lightning Experience
    查看>>
    map[]和map.at()取值之间的区别
    查看>>
    VTK:可视化之RandomProbe
    查看>>
    【编程】C语言入门:1到 100 的所有整数中出现多少个数字9
    查看>>
    pair的用法
    查看>>
    javaWeb服务详解(含源代码,测试通过,注释) ——Emp的Dao层
    查看>>
    echarts 基本图表开发小结
    查看>>
    TreeSet、TreeMap
    查看>>
    GitHub上传时,项目在已有文档时直接push出现错误解决方案
    查看>>
    嵌入式系统试题库(CSU)
    查看>>
    00010.02最基础客户信息管理软件(意义类的小项目,练习基础,不涉及数据库)
    查看>>
    00013.05 字符串比较
    查看>>
    UE4 错误列表 error码(只记录我遇到的情况,持续添加,未完成)
    查看>>
    cmd编译.java文件 : java:720: 错误: 编码GBK的不可映射字符 Why ? ? ? ?
    查看>>
    Android 架构组件 – 让天下没有难做的 App
    查看>>
    能解决数据可视化大屏需求的3款可视化工具
    查看>>
    第01问:MySQL 一次 insert 刷几次盘?
    查看>>