PLSQL_性能优化系列14_Oracle High Water Level高水位分析

2014-10-04 BaoXinjian

一、摘要



高水位线好比水库中储水的水位线,用于描述数据库中段的扩展方式。高水位线对全表扫描方式有着至关重要的影响。

当使用delete 操作表记录时,高水位线并不会下降,随之导致的是全表扫描的实际开销并没有任何减少。

本文给出高水位线的描述,如何降低高水位线,以及高水位线对全表扫描的影响。

1. 何谓高水位线

如前所述,类似于水库中储水的水位线。只不过在数据库中用于描述段的扩展方式。

可以将数据段或索引段等想象为一个从左到右依次排开的一系列块。当这些块中未填充任何数据时,高水位线位于块的最左端(底端)

随着记录的不断增加,新块不断地被填充并使用,高水位线随之向右移动。高水位线之上为未格式化的数据块。

删除(delete)操作之后,高水位线之下的块处于空闲状态,但高水位线并不随之下降,直到重建,截断或收缩表段。

全表扫描会扫描高水位线之下的所有块,包括空闲数据块(执行了delete操作)。

2. 低高水位线

是在使用ASSM时的一个概念。即使用ASSM时除了高水位线之外,还包括一个低高水位线。低高水位线一定是位于高水位线之下。

当段使用MSSM管理方式时只有一种情况即只存在一个高水位线。

使用MMSM时,当HWM升高时,Oracle立即格式化所有块且有效,并可以安全读取。仅当第一次使用时完成格式化,便于安全读取数据。

使用ASSM时,当HWM升高时,Oracle并不会立即格式化所有块。仅当第一次使用时完成格式化,便于安全读取数据。

使用低高水位线可以减少当全面扫描表段时,低高水位线与高水位线之间不安全块的检查数量。即低高水位线之下的块不再检查。

二、案例 - Delete / SHRINK SPACE CASCADE / Truncate Table 对水位线的影响



1. 创建测试表和资料,并分析

Step1. 创建表

CREATE TABLE sh.bxj_high_water_level
AS
       SELECT   ROWNUM AS id,
                ROUND (DBMS_RANDOM.normal * 1000) AS val1,
                DBMS_RANDOM.string (‘p‘, 250) AS pad
         FROM   DUAL
   CONNECT BY   LEVEL <= 10000;

Step2. 收集表的统计信息

BEGIN
   DBMS_STATS.gather_table_stats (‘SH‘,
                                  ‘BXJ_HIGH_WATER_LEVEL‘,
                                  cascade   => TRUE);
END; 

ANALYZE TABLE sh.bxj_high_water_level COMPUTE STATISTICS;

Step3. 表的统计信息和Block信息

SQL> select count(*) from sh.bxj_high_water_level;

Execution Plan
----------------------------------------------------------
Plan hash value: 4214873579

-----------------------------------------------------------------------------------
| Id  | Operation          | Name                 | Rows  | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                      |     1 |   107   (0)| 00:00:02 |
|   1 |  SORT AGGREGATE    |                      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| BXJ_HIGH_WATER_LEVEL | 10000 |   107   (0)| 00:00:02 |
-----------------------------------------------------------------------------------

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        375  consistent gets
          0  physical reads
          0  redo size
        422  bytes sent via SQL*Net to client
        419  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

2. Delete Record 对水位线的影响

Step1. 删除表中记录

DELETE FROM sh.bxj_high_water_level WHERE ROWNUM <= 9900;

Step2. 收集表的统计信息

BEGIN
   DBMS_STATS.gather_table_stats (‘SH‘,
                                  ‘BXJ_HIGH_WATER_LEVEL‘,
                                  cascade   => TRUE);
END; 

ANALYZE TABLE sh.bxj_high_water_level COMPUTE STATISTICS;

Step3. 表的统计信息和Block信息

SQL> select count(*) from sh.bxj_high_water_level;

Execution Plan
----------------------------------------------------------
Plan hash value: 4214873579

-----------------------------------------------------------------------------------
| Id  | Operation          | Name                 | Rows  | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                      |     1 |   107   (0)| 00:00:02 |
|   1 |  SORT AGGREGATE    |                      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| BXJ_HIGH_WATER_LEVEL |   100 |   107   (0)| 00:00:02 |
-----------------------------------------------------------------------------------

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        375  consistent gets
          0  physical reads
          0  redo size
        422  bytes sent via SQL*Net to client
        419  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

3.  SHRINK SPACE CASCADE 对水位线的影响

Step1。合并控件

ALTER TABLE sh.bxj_high_water_level ENABLE ROW MOVEMENT;     

ALTER TABLE sh.bxj_high_water_level SHRINK SPACE CASCADE;   

ALTER TABLE sh.bxj_high_water_level DISABLE ROW MOVEMENT;  

Step2. 收集表的统计信息

BEGIN
   DBMS_STATS.gather_table_stats (‘SH‘,
                                  ‘BXJ_HIGH_WATER_LEVEL‘,
                                  cascade   => TRUE);
END; 

ANALYZE TABLE sh.bxj_high_water_level COMPUTE STATISTICS; 

Step3. 表的统计信息和Block信息

SQL> select count(*) from sh.bxj_high_water_level;

Execution Plan
----------------------------------------------------------
Plan hash value: 4214873579

-----------------------------------------------------------------------------------
| Id  | Operation          | Name                 | Rows  | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                      |     1 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |                      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| BXJ_HIGH_WATER_LEVEL |   100 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          6  consistent gets
          0  physical reads
          0  redo size
        422  bytes sent via SQL*Net to client
        419  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

4. Truncate Table 对水位线的影响

Step1. Truncate 表

TRUNCATE TABLE sh.bxj_high_water_level

Step2. 收集表的统计信息

BEGIN
   DBMS_STATS.gather_table_stats (‘SH‘,
                                  ‘BXJ_HIGH_WATER_LEVEL‘,
                                  cascade   => TRUE);
END; 

ANALYZE TABLE bxj_water_level COMPUTE STATISTICS;

Step3. 表的统计信息和Block信息

SQL>  select count(*) from sh.bxj_high_water_level;

Execution Plan
----------------------------------------------------------
Plan hash value: 4214873579

-----------------------------------------------------------------------------------
| Id  | Operation          | Name                 | Rows  | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                      |     1 |     2   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |                      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| BXJ_HIGH_WATER_LEVEL |     1 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        421  bytes sent via SQL*Net to client
        419  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

六、案例 - 总结



(1). 高水线直接决定了全表扫描所需要的I/O开销

(2). delete操作不会降低高水位线,高水位线之下的所有块依然被扫描

(3). 使用truncate 会重置高水位线到0位

(4). 定期使用alter table tab_name shrink space cascade 有效减少该对象上的I/O开销

参考:了沙弥 http://blog.csdn.net/leshami/article/details/6949179

时间: 2024-10-05 04:49:45

PLSQL_性能优化系列14_Oracle High Water Level高水位分析的相关文章

PLSQL_性能优化系列16_Oracle High Water Level高水位分析

2014-10-04 BaoXinjian 一.摘要 高水位线好比水库中储水的水位线,用于描述数据库中段的扩展方式.高水位线对全表扫描方式有着至关重要的影响. 当使用delete 操作表记录时,高水位线并不会下降,随之导致的是全表扫描的实际开销并没有任何减少. 本文给出高水位线的描述,如何降低高水位线,以及高水位线对全表扫描的影响. 1. 何谓高水位线 如前所述,类似于水库中储水的水位线.只不过在数据库中用于描述段的扩展方式. 可以将数据段或索引段等想象为一个从左到右依次排开的一系列块.当这些块

[转]Oracle High Water Level高水位分析

PLSQL_性能优化系列14_Oracle High Water Level高水位分析 http://www.cnblogs.com/eastsea/p/4005814.html 一.摘要 PLSQL_性能优化系列14_Oracle High Water Level高水位分析 高水位线好比水库中储水的水位线,用于描述数据库中段的扩展方式.高水位线对全表扫描方式有着至关重要的影响. 当使用delete 操作表记录时,高水位线并不会下降,随之导致的是全表扫描的实际开销并没有任何减少. 本文给出高水位

PLSQL_性能优化系列14_Oracle Index Anaylsis索引分析

2014-10-04 BaoXinjian 一.摘要 1. 索引质量 索引质量的高低对数据库整体性能有着直接的影响. 良好高质量的索引使得数据库性能得以数量级别的提升,而低效冗余的索引则使得数据库性能缓慢如牛,即便是使用高档的硬件配置. 因此对于索引在设计之初需要经过反复的测试与考量. 那对于已经置于生产环境中的数据库,我们也可以通过查询相关数据字典得到索引的质量的高低,通过这个分析来指导如何改善索引的性能. 2. 索引创建的基本指导原则 索引的创建应遵循精而少的原则 收集表上所有查询的各种不同

PLSQL_性能优化系列16_Oracle DataScan数据扫描

对数据的读取操作是非常消耗资源的,如何减少对数据的扫描,是提升sql效率的一个重要方面,例如物化视图技术.本篇介绍几种sql写法,分别是CASE expression/DML with returning clause /multitable insert.[@[email protected]] 一. 用CASE EXPRESSION将多句查询组合在一起SELECT COUNT (*)FROM employeesWHERE salary < 2000;SELECT COUNT (*)FROM

PLSQL_性能优化系列01_Oracle Index索引

2014-06-01 BaoXinjian 一.摘要 在PLSQL查询优化中,使用和接触最多的应该是索引Index这个概念,个人也觉得对Index选择和优化是程式优化过程中比较重要的概念,特别是刚开始接触PLSQL性能优化 索引的一些概念 一个索引可以由一个或多个列组成, 对列设置索引其实就是对列的内容按一定的方式进行排序,检索数据的时候,检索排过序的数据,检索到最后一个有效数据之后就跳出检索 这样就不必进行全表扫描了,同时可以应用很多算法提高检索效率 数据库多用二分法检索数据 索引的连接方式

PLSQL_性能优化系列04_Oracle Optimizer优化器

2014-09-25 BaoXinjian 一.摘要 1. Oracle优化器介绍 本文讲述了Oracle优化器的概念.工作原理和使用方法,兼顾了Oracle8i.9i以及最新的10g三个版本.理解本文将有助于您更好的更有效的进行SQL优化工作. 2. RBO优化器 RBO是一种基于规则的优化器,随着CBO优化器的逐步发展和完善,在最新的10g版本中Oracle已经彻底废除了RBO. 正在使用Oracle8i或9i的人们或多或少的都会碰到RBO,因此在详细介绍CBO之前,我们有必要简单回顾一下古

PLSQL_性能优化系列08_Oracle Insert / Direct Insert性能优化

2014-09-25 BaoXinjian 一.Insert 性能影响 应用设计不合理导致的session之间的互锁(enqueue)是影响程序可扩展性最常见的原因.此外,一些共享资源的争用,也会导致性能下降. 本篇介绍两个由并发insert操作导致的等待事件(wait event),以及如何通过优化物理设计来进行改善. 普通Insert操作本身产生的是行锁,因此进程相互之间不会锁住(enqueue),但当很多进程insert同一张表时,会有资源上冲突. 以下是两个例子: 1. Buffer b

PLSQL_性能优化系列06_Oracle Soft Parse / Hard Parse软硬解析

2014-08-11 BaoXinjian 一.摘要 Oracle硬解析和软解析是我们经常遇到的问题,所以需要考虑何时产生软解析何时产生硬解析,如何判断 1. SQL的执行过程 当发布一条SQL或PL/SQL命令时,Oracle会自动寻找该命令是否存在于共享池中来决定对当前的语句使用硬解析或软解析. 通常情况下,SQL语句的执行过程如下: Step1. SQL代码的语法(语法的正确性)及语义检查(对象的存在性与权限). Step2. 将SQL代码的文本进行哈希得到哈希值. Step3. 如果共享

PLSQL_性能优化系列07_Oracle Parse Bind Variables解析绑定变量

2014-09-25 BaoXinjian 一.绑定变量用法和使用场合 使用绑定变量的重要性:如果不使用绑定变量而使用常量,会导致大量硬解析.由于硬解析的种种危害,不使用绑定变量往往是影响oracle性能和扩展性的最大问题 以下为一些错误写法和正确写法的例子 1. PLSQL中普通查询 (1). 错误写法 SELECT * FROM emp WHERE empno=123; (2). 正确写法(未使用绑定变量) Empno:=123;SEELCT* FROM emp WHERE empno=:e