• SQL脚本存在TABLE ACCESS FULL行为及其优化



    SQL脚本存在TABLE ACCESS FULL行为


    对于SQL的执行计划,一般尽量避免TABLE ACCESS FULL的出现,那怎样去定位,系统里面哪些SQL脚本存在TABLE ACCESS FULL行为,对于9i及以后版本,使用以下语句即可

    select *
      from v$sql_plan v
    where v.operation = 'TABLE ACCESS'
       and v.OPTIONS = 'FULL'
       and v.OBJECT_OWNER='MS';--指定用户下

    查询得到SQL_ID,以及ADDRESS,HASH_VALUE,PLAN_HASH_VALUE,OBJECT_NAME后,就可以定位到具体的SQL语句了。

    如:

    select s.SQL_TEXT
      from v$sqlarea s
    where s.SQL_ID = '4dpd97jh2gzsd'
       and s.HASH_VALUE = '1613233933'
       and s.PLAN_HASH_VALUE = '3592287464';

    或者

    select s.SQL_TEXT from v$sqlarea s where s.ADDRESS = '00000000A65D2318';


    ORACLE优化之执行规划 - TABLE FULL SCAN/INDEX FULL SCAN

    TABLE FULL SCAN :  全表扫描,表示表中所有记录都被访问到。如果表很大,  该操作对查询性能的影响会很大,此时,建议使用索引  或去掉查询中的LIKE操作。
     

    如:
      EXPLAIN PLAN
       SET statement_id = 'ex_plan1' FOR
       SELECT phone_number FROM employees
       WHERE phone_number LIKE '650%';


    INDEX RANGE SCAN [DESCENDING] :  从相关索引中获取了一个或多个ROWID。  当查询条件字段具有非唯一索引,或者查询过滤条件是一个范围,  ORACLE将会采用该操作。
     
      示例:
       SELECT * FROM t_employee WHERE id > 11001;
       SELECT * FROM t_employee WHERE first_name = 'Tommy';
      
       此例中,id是关键字,first_name具有非唯一索引。   oracle会对此两个索引采用INDEX RANGE SCAN.
     
    INDEX FULL SCAN [DESCENDING]:  从相关的索引中获取了所有的ROWID。由于是按索引的顺序访问和获取ROWID,  因此获得的ROWID是直接排过序的。
     
      示例1:
       SELECT /*+ INDEX(T_EMPLOYEE IDX_NODES_ID)*/ id from T_EMPLOYEE;
     
       示例中使用了HINT要求强制使用索引查询,但未指定索引字段的过滤条件,   于是ORACLE将采用INDEX FULL SCAN操作。由于该操作按索引顺序或去记录,   因而返回的ID列表是排过序的。
     
      示例2:
       SELECT * FROM T_EMPLOYEE WHERE MIDDLE_NAME IS NULL;
      
       当MIDDLE_NAME字段可以为NULL,且具有非唯一索引,ORACLE在执行此语句时,   可能会采用INDEX FULL SCAN操作。   但在某些情况下,比如该语句已经执行过一遍,相关数据已经加载到内存,   那么,ORACLE的执行规划也可能会直接选择TABLE FULL SCAN操作,可能   是ORACLE认为此时直接TABLE FULL SCAN的性能会比INDEX FULL SCAN高。
     
    INDEX FAST FULL SCAN
      从相关索引中获取所有的ROWID。该操作同时从多个索引数据块中扫描数据,  所以结果并不是排序的。用于对索引字段进行查询。
     
      示例:SELECT id FROM T_EMPLOYEE;  其中id为表的主键索引字段。
     
     
    优化策略:
      一般情况下,尽量避免FULL SCAN,特别是TABLE FULL SCAN和INDEX FULL SCAN.  在查询大表的情况下,INDEX RANGE SCAN会显著提高查询性能。但在查询小表时,  INDEX可能反而对性能产生不利影响。


    oracle创建索引

    数据库索引是为了提高查询速度的一种数据结构。

    索引的创建语句

    索引的创建语句非常简单。

    CREATE INDEX 索引名 ON 表名(列名);

    除了单列索引,还可以创建包含多个列的复合索引。

    CREATE INDEX 索引名 ON 表名(列名1, 列名2, 列名3, ...);

    删除索引也非常简单。

    DROP INDEX 索引名;

    查看某个表中的所有索引也同样简单。

    SELECT * FROM ALL_INDEXES WHERE TABLE_NAME = '表名'

    还可以查看某个表中建立了索引的所有列。

    SELECT * FROM ALL_IND_COLUMNS WHERE TABLE_NAME = '表名'

    索引的建立原则

    1.索引应该建立在WHERE子句中经常使用的列上。如果某个大表经常使用某个字段进行查询,并且检索的啊行数小于总表行数的5%,则应该考虑在该列上建立索引。

    2.对于两个表连接的字段,应该建立索引。

    3.如果经常在某表的一个字段上进行Order By的话,则也应该在这个列上建立索引。

    4.不应该在小表上建立索引。

    索引的优缺点

    索引主要是为了提高数据的查询速度,这就是索引的优点。但是当进行增删改的时候,会更新索引。因此索引越多,增删改的速度就会越慢,因为有一个维护索引的过程。创建索引之前需要权衡该字段是否经常发生增删改操作,否则可能会带来负优化的问题。

    索引的优点

    1.很大地提高了数据的检索速度。

    2.创建唯一索引能保证数据库表中每一行数据的唯一性(唯一性约束)。

    3.提高表与表之间的连接速度。

    索引的缺点

    1.索引需要占用物理空间。

    2.当对表中的数据进行增加、删除和修改的时候,索引也要动态地进行维护,降低数据的维护速度。

    关于查询优化器

    当Oracle拿到SQL语句的时候,会使用查询优化器去分析该语句,并根据分析结果生成查询执行计划。也就是说,数据库是执行的查询计划,而不是SQL语句。

    查询优化器有RBO(Rule-Based-Optimizer,基于规则的查询优化器)和CBO(Cost-Based-Optimizer,基于成本的查询优化器),其中基于规则的查询优化器在10g的版本中彻底消失了。原因是因为RBO最后的查询都是全表扫描,而CBO会根据统计信息选择最优的查询方案。

    因此,CBO一旦发现有索引的存在,并且这个索引能帮助提高查询速度,就是使用通过索引进行查询的方法。

    oracle 索引的几种类型

    1. b-tree索引
    Oracle数据库中最常见的索引类型是b-tree索引,也就是B-树索引,以其同名的计算科学结构命名。CREATE
    INDEX语句时,默认就是在创建b-tree索引。没有特别规定可用于任何情况。
    2. 位图索引(bitmap index)
    位图索引特定于该列只有几个枚举值的情况,比如性别字段,标示字段比如只有0和1的情况。
    3. 基于函数的索引
    比如经常对某个字段做查询的时候是带函数操作的,那么此时建一个函数索引就有价值了。
    4. 分区索引和全局索引
    这2个是用于分区表的时候。前者是分区内索引,后者是全表索引
    5. 反向索引(REVERSE)
    这个索引不常见,但是特定情况特别有效,比如一个varchar(5)位字段(员工编号)含值
    (10001,10002,10033,10005,10016..)
    这种情况默认索引分布过于密集,不能利用好服务器的并行
    但是反向之后10001,20001,33001,50001,61001就有了一个很好的分布,能高效的利用好并行运算。
    6.HASH索引
    HASH索引可能是访问数据库中数据的最快方法,但它也有自身的缺点。集群键上不同值的数目必须在创建HASH集群之前就要知道。需要在创建HASH集群的时候指定这个值。使用HASH索引必须要使用HASH集群。

  • 相关阅读:
    Gridview利用DataFormatString属性设置数据格式
    Sqlserver 字符串操作
    解决“网络不存在或尚未启动”
    ASP.NET中Url重写后,打不开真正的Html页面
    jquery 清空表单
    Sqlserver2005远程访问
    FCKeditor 在Ie中弹出“未知工具栏项目”的暂时解决方法
    表单成功提交了,点后退显示网页过期
    找不到方法:“Void System.Web.UI.HtmlControls.HtmlForm.set_Action(System.String)”。
    LINQ 标准的查询操作符 设置操作符号 两个结果集的 并、交、差、唯一
  • 原文地址:https://www.cnblogs.com/ios9/p/13176029.html
Copyright © 2020-2023  润新知