• oracle 10gR2 sql查询性能相关摘要


    http://lzfhope.blog.163.com/blog/static/6363992200811296039755/?suggestedreading&wumii

     环境:ORACLE 10G
         这里着重要研究的是一些很常见的,但是有和性能有密切关系的写法。
         不讨论函数,索引,分区等等因素,主要是SQL引擎的执行计划,具体一点就是:连接,条件,视图(主要是内建视图)。
         限于本人对于SQL引擎的了解,这里逐一列举几个例子。
         一) 关于 where 条件后面的常量表达式,例如1=1
         事实上,这是为了方便编写动态sql而写的 ,有的人也到处都这么写,仅仅是因为一个习惯,但是不建议到处写。会不会影响性能呢? 结论是 基本上不会影响,为什么呢? 因为10g的SQL引擎在解析前已经把这个条件过滤掉了。
         推而广之,其实大部分最终可以变为常量的表达式,都会在解析的时候被计算为常量:一个字符串,一个数值,或者一个布尔变量。 
         如果存在这样的一个where 子句
             (1=1) and  xxx ,那么会解析为 xxx.
               (1>1)   and xxx     ,会解析为 false ,并且不执行查询
               (1=1)  or  xxx ,        解析为  xxx 
               (1>1)  or xxx        , 解析为 false ,并且不执行查询.
                cola>100/2         ,会解析为cola>50 
         所以,针对很久以前的sql解析的法则,现在已经不通了,大家写的时候也不要再去关注,当然cola>100/2还是写成cola>50 比较好,无论如何解析也是需要花费时间的。
         二)关联条件还是过滤条件的选择
         例如有两个表格,  
          员工表  a(id,dept,name)  ,  工资表b(id,mon,salary)
          查询特定月份每个部门累计工资,可以如下编写
          select a.dept,sum(b.salary) from
                     a join b on b.id=a.id  where b.mon = 200812 group by  a.dept
          也可以如此写
          select a.dept,sum(b.salary) from
                     a join b on b.id=a.id  and b.mon = 200812 group by  a.dept
          它们的分析计划是一样的,这是因为对于oracle 10g的SQL引擎而言,可以单单作用于一个表格上的条件,是需要先在表格内部处理,然后才会处理其它步骤。
           上例子是针对join(简单连接或者内连接),我的结论是:选择关联条件还是过滤条件对于内连接是没有差别的。
      如果是外部连接(outer)或者其它连接(anti 差,semi 交)则另当别论!
      如果结合上索引情况会更复杂,不过这里暂时不说索引的事情。
      无论如何,谨记尽量使用explain 分析sql语句是很重要的。并且在很多时候注意使用hint,因为即使是执行计划,也不是很可信的。      
         三) 表格顺序
      曾经,有人说,表格的顺序很重要。
      我说,没错,但那仅仅是曾经而已,对于10g而言,这些发生了变化。
         现在要下两个结论:
      1)如果都是inner join(无论是否有明确指定顺序的),那么oracle会自动地在结果集合比较小的那个表格开始执行 (不考虑索引,条件等)。下一个表格是什么则取决于第一表关联的对象,然后才是其它。
            例如  select a.*,b*,c* from a,b,c where a.id=b.id and c.id=a.id
           select  a.*,b*,c* from a join b on b.id=a.id join c on c.id=a.id
         2)一切以执行计划为准,但可以通过调整语句来改变执行计划。

     http://lzfhope.blog.163.com/blog/static/636399220082214551786/

     3.2 DISTINCT|UNIQUE
            我们可以希望只返回重复行中的一行,那么可以在语句中设置distinct或者unique.
            限制:1)当设置了distinct或者unique的时候,select语句列表中的列所包含的所有字节总数是受到限制的,必须等于数据块的大小减去一些负载信息(不是很明白)?. the total number of bytes in all select list
    expressions is limited to the size of a data block minus some overhead 。2)如果列包含了lob,那么不能使用distinct或者unique。

     3.9)样品(抽样)语句(sample clause)
             使用抽样语句,可以只随机选择一部分数据,而不是所有的数据.包括行随机抽样(sample),以及块随机抽样(block).   
             语法 select * from tab sample(N) seed(S)
        例子: 
                       SQL> select * from test_flashback sample(50);          
                       SID FULLNAME
                ---------- ----------------------------------------
                       101 天南地北          
                SQL> select * from test_flashback sample(50);          
                       SID FULLNAME
                ---------- ----------------------------------------
                       101 天南地北
                       101 五湖四海          
                SQL> select * from test_flashback sample(50);          
                       SID FULLNAME
                ---------- ----------------------------------------
                       101 五湖四海
                       101 三山五岳
       其中函数sample(N),N是在区间[0.000001,100)之内的数,可以称呼为命中率.表格或者视图的数据越多则这个函数的效果越好。这个函数在某些时候还是非常有用的.SEED(S)中的S介于[0,4294967295]之间,该函数主要是用于保证返回的结果集合和前次的同样S取值的一样。
      要保证采取块抽取,则可以用 /*+full*/ 或者/*+INDEX_FFS*/的强制提示来执行语句。
      限制:1)只有一个视图是包含主键的时候,才可以用抽样语句;2)在DML语句的子查询中不能使用抽样语句.  

  • 相关阅读:
    Django进阶之session
    Windows下MySQL下载安装、配置与使用
    Windows下安裝並設置Redis
    mysql root密码忘记
    .net core 持续构建简易教程
    SqlServer简单数据分页
    产品规划之战略规划;
    C#Excel文件加密实现,支持xlsx、docx、pptx(C#NetAsp.Net)
    仿QQ空间根据位置弹出PopupWindow显示更多操作效果
    Windows编译Nginx源码
  • 原文地址:https://www.cnblogs.com/rattersnake/p/2993449.html
Copyright © 2020-2023  润新知