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

        项目中尽管使用了orm映射,但Oracle系统的优化还是非常有价值的,这里从sql语句的角度对经常使用的语句做下总结。

    1、from字段中的优化:
         Oracle安照从右到左的顺序载入表数据,应该把能够排除数据最多的表放到后面(基础表)。


         比方。在关联查询中。把课程表放到后面。成绩表放到前面。由于课程表数据一般比較少,关联的时候能够高速的过滤掉一些成绩数据。

    2、where中的优化:
         对能够过滤数据最多的,放到后面,原理也是Oracle运行从下到上(从右到左)的顺序。

    3、使用列名替代*:

         省去从字典表中解析的过程 :
         Oracle运行sql语句过程: 
         在共享池中搜索sql语句是否已经存在
         验证sql是否语法精确
         运行数据字典验证表和列的定义
         获取对象的分析锁。以便在语句的分析过程中对象的定义不会改变
         检查用户是否具有对应的操作权限
         确定语句最佳运行计划
         将语句和运行方案保存到共享的sql区。

    4、使用?參数形式:
         尽量不要使用拼接字串的方式。由于带有?的參数形式会缓存分析结果。省去上面非常多步骤。

    5、使用decode函数:
         decode不会反复扫描同样记录或反复连接同样的表,降低表的扫描次数。

    6、使用truncate替代delete:
         delete:逐条删除。并保存回滚还原点。

    DML(数据操作语言insert,update,delete,merge)
         truncate不会保存回滚点,是DDL(数据定义语言,如drop,alter)
         在oracle里DML是能够rollback的,而DDL是不能够的

         假设数据量大,区别非常大的。

    7、尽量多用commit:
         Oracle仅仅有在commit后才会提交(差别于sqlserver)。假设没有提交,会在内存中保存非常多数据。commit后释放的资源有:
         回滚上段用于恢复数据库的记录信息
         被程序语句获得的锁
         Redo log buffer中的空间
         为管理上述3种资源的内部花费

    8、使用where语句替代having子句:
         在分组或者配合group的时候会使用having。
         where会直接过滤掉数据。使用having往往会配合group。检索出数据后,会带着数据进行排序、统计等。
    9、on/where/having排序使用顺序:
        on:做的是数据映射,在映射时,把无用的数据直接过滤掉了
        where:先进行一个全表的搜索,之后再进行数据筛选
        where又比having要快,having中带的垃圾数据相同也做了运算

    10、降低对表的查询:
         在含有子查询的sql语句中,要特别注意降低对表的查询。

        Select tab_name from tables where (tab_name,db_ver)=(select tab_name,db_ver from tab_columns where version=604)
    11、使用表别名:

         降低对sql语句解析的时间并降低由多个表同样的Column名歧义引起的语法错误
        假设不使用别名,会去字典表中查找,推断是否有列名歧义。


    12、使用exists替代in not exists替代not in:
        Oracle採用命中即返回的方式。在多表链接查询时,假设使用in会导致子查询的表全表遍历,并排序、合并,这时候能够使用外链接或not  exists 替代。

    13、识别低效率运行的语句:
        各种sql优化的图形工具层出不穷。但能够写出自己的sql工具来解决这个问题
    Select executions, disk_reads, buffer_gets, round((buffer_gets-disk_reads)/buffer_gets,2) hit_radio,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;


    14、使用索引:

        使用于查询的表。提供了主键的唯一性验证,long或者long raw数据类型,差点儿能够索引全部列
    定期重建索引,在删除和改动多的表。不适用索引。原因,不解释了。

        注意,并非创建了索引后就一定会走索引。使用索引的时候,不能使用索引进行一些计算。否则失效
    使用索引快于全表扫描,在多表连接使用索引提高效率。


       避免在索引上使用not:

         会停止索引(not表示的是:没有什么, 而索引表示的是:有什么)

       用exitsts替代distinct:

         在提交一个包括一对多表信息(部门和雇员表)的查询时使用。原因:查找即返回原理

       避免在索引列上使用计算:
         低效:
         Select * from dept  where sal * 12 >25000
         高效:
         Select * from dept where sal> 25000/12

        避免在索引列上使用is null 和 is not null:
         由于索引不会对null数据类型进行索引,索引仅仅是记录有什么
         对于单列索引。不会进行索引
         对于符合索引。假设全部列多为空,不进行索引,仅仅要有一个列不空。就索引。

        在Oracle中空不等于空,所以,就会插入若干条同样键值的记录。而他们的值都是空,而空值不进行索引,所以,当进行空值比較时。会使用Oracle。停止使用该索引。
        低效:
         Select …. From dep where dep_code is not null;
         高效:
         Select …. From dep where dep_code >=0;这里也会过滤掉null列

         总是使用索引的第一个列:

          假设索引建立在多个列上。仅仅有咋他的第一个列。被where自居引用时,优化器才会选择使用该索引,当仅使用索引的第二个列是,优化器会忽略索引,使用全表索引。


    15、>=是直接定位:

          假设使用 >还须要一个推断的过程。
    16、使用union替代where字句中的or:
         对索引列使用or会导致全表扫描。针对多个索引列有效

    17、在oracle8i下,两者运行路径似乎同样,但能用in的就别用or。
    18、使用union-all:

        union-all:不排序,查询全部的,只是滤反复的
        nuion:排序(优化sort_raea_size这块内存),过滤反复的。

    19、order by 用where 限定:

         order by名中索引的条件比較苛刻
        排序列必须包括在同样的索引中,并保持索引中的排列顺序。Order by中全部列不能定义为空。

    20、须要当心的where子句:
         !=将不使用索引
         ||字符连接函数。会停用索引
         + - *  /  会停用索引 
        同样的索引列不能互相比較,否则会启用全表扫描

    21、使用大写:
        Oracle中会把全部的语句转换成大写,
        有些内部表。如。查询表名时,推断某个表是否存在。假设是大写有效,小写就是无效的

    22、依据磁盘读写速率调整块的大小:

         一个Oracle数据库中。表空间、段、区、数据块的概念,能够依据server的I/O性能调整块的大小。

    总结:

        上面的点分的非常细,他们都是依据Oracle的内部原理总结出的经常使用规律,所以,掌握原理要比记住这些跳跳框架更加重要。经常使用的规则有:

        Oracle依照从右到左,从下至上的运行顺序

        在检索数据的时候,往往遵循查到即返回的原则

        索引,记录的是有哪些数据,所以。不要在索引列上直接使用排除不存在条件的查询,也不要在索引上进行计算

        Oracle觉得空不等于空

        where命中索引的几率比較高,通常情况下。优先选择使用where。


    另外推荐一些不错的链接:

    http://blog.csdn.net/tianlesoftware/article/details/7008801

    http://blog.csdn.net/lk_blog/article/details/7585540



    
  • 相关阅读:
    2017《Java技术》预备作业 计科1501 杨欣蕊
    Java技术预备作业02杨欣蕊
    系统无法从光盘启动
    动态数组ArrayList的使用
    dbgrid数据显示和数据源不同
    异步任务判断服务器是否开启
    Java字符串格式化
    思科2960 监听端口设置
    64位win7安装jdk和eclipse
    Delphi临界区的使用
  • 原文地址:https://www.cnblogs.com/llguanli/p/8328515.html
Copyright © 2011-2022 走看看