oracle表碎片的整理分析

技术oracle表碎片的整理分析本篇文章给大家分享的是有关oracle表碎片的整理分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

本文将与您分享oracle表片段的排序和分析。边肖觉得挺实用的,所以分享给大家学习。希望你看完这篇文章能有所收获。我们就不多说了。让我们和边肖一起看看。

在数据库的日常使用中,由于不断的插入、删除和更新操作,不可避免地会出现表和索引碎片化的情况。如果碎片多,sql的执行效率自然会很差。原因很简单。高水位线(HWL)下的很多数据块没有数据,但是高水位线的数据块在扫描整个表的时候要扫描!

表的碎片不同于文件系统的碎片。当一个表上的DML操作越来越多的时候,HWM之前可能有大量的空闲空间,在读取表的时候,会读入HWM以下的块,这样会产生更多的IO,从而影响性能。只有DDL操作会导致表收缩。

要对表进行碎片整理,有:1种碎片整理方法,使用alter MOVE表,然后重建索引;2.使用alter table启用行移动;然后alter table收缩空间级联(收缩用途有限,所以要注意);3、通过创建表格XXX作为从abb选择*的方式;4.使用导出和导入表;

实验如下:

SQL从dba_objects中将表t1创建为select *;Table created.SQL select count(*) from t1; COUNT(*)---------- 86956SQL insert into t1 select * from t1;86956 rows created.SQL commit;http://

SQL从dba_tables中选择OWNER、TABLE_NAME、TABLE_NAME、NUM_ROWS、BLOCKS、EMPTY_BLOCKS、AVG_SPACE、AVG_ROW_LEN、LAST_ANALYZED,其中TABLE _ NAME=' T1

所有者表名表空间名行数块空块AVG空间AVG行最后分析Commit complete.SQL

      SYSTEM

SQL> COL SEGMENT_NAME FOR A15
SQL> select OWNER,SEGMENT_NAME,TABLESPACE_NAME,BYTES,BLOCKS,EXTENTS from dba_segments where segment_name in ('T1','IDX_T1_ID');

OWNER                          SEGMENT_NAME    TABLESPACE_NAME                     BYTES     BLOCKS    EXTENTS
------------------------------ --------------- ------------------------------ ---------- ---------- ----------
SYS                            T1              SYSTEM                           20971520       2560         35
SYS                            IDX_T1_ID       SYSTEM                            4194304        512         19

可以看到dba_segment中已经可以记录表大小,而dba_tables则没有。

--使用dbms_stats手机统计信息
SQL> exec dbms_stats.gather_table_stats('SYS','T1',CASCADE=>TRUE);

PL/SQL procedure successfully completed.

SQL>

SQL> select OWNER,TABLE_NAME,TABLESPACE_NAME,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,AVG_ROW_LEN,LAST_ANALYZED from dba_tables where TABLE_NAME='T1';

OWNER                          TABLE_NAME      TABLESPACE_NAME   NUM_ROWS     BLOCKS EMPTY_BLOCKS  AVG_SPACE AVG_ROW_LEN LAST_ANALYZED
------------------------------ --------------- --------------- ---------- ---------- ------------ ---------- ----------- -------------------
SYS                            T1              SYSTEM              173912       2476            0          0          98 2017-10-26 05:35:37

SQL> select OWNER,SEGMENT_NAME,TABLESPACE_NAME,BYTES,BLOCKS,EXTENTS from dba_segments where segment_name in ('T1','IDX_T1_ID');

OWNER                          SEGMENT_NAME    TABLESPACE_NAME      BYTES     BLOCKS    EXTENTS
------------------------------ --------------- --------------- ---------- ---------- ----------
SYS                            T1              SYSTEM            20971520       2560         35
SYS                            IDX_T1_ID       SYSTEM             4194304        512         19

发现dba_table中已有记录BLOCKS块大小记录,但是没有empty_blocks空块记录和AVG_SPACE值。

--需要使用analyze子句收集表t1的空块信息。
DBMS_STATS包无法获取EMPTY_BLOCKS统计信息,所以需要用analyze命令再收集一次统计信息

SQL> analyze table t1 compute statistics;

Table analyzed.

SQL> select OWNER,TABLE_NAME,TABLESPACE_NAME,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,AVG_ROW_LEN,LAST_ANALYZED from dba_tables where TABLE_NAME='T1';

OWNER                          TABLE_NAME      TABLESPACE_NAME   NUM_ROWS     BLOCKS EMPTY_BLOCKS  AVG_SPACE AVG_ROW_LEN LAST_ANALYZED
------------------------------ --------------- --------------- ---------- ---------- ------------ ---------- ----------- -------------------
SYS                            T1              SYSTEM              173912       2476           83        863         101 2017-10-26 05:38:18

SQL> select OWNER,SEGMENT_NAME,TABLESPACE_NAME,BYTES,BLOCKS,EXTENTS from dba_segments where segment_name in ('T1','IDX_T1_ID');

OWNER                          SEGMENT_NAME    TABLESPACE_NAME      BYTES     BLOCKS    EXTENTS
------------------------------ --------------- --------------- ---------- ---------- ----------
SYS                            T1              SYSTEM            20971520       2560         35
SYS                            IDX_T1_ID       SYSTEM             4194304        512         19

发现dba_tables中的 EMPTY_BLOCKS  AVG_SPACE AVG_ROW_LEN字段有值了,且AVG_ROW_LEN的值发生了变化。

--计算表在高水位线下还有多少空间可用,这个值应当越低越好,表使用率越接近高水位线,全表扫描所做的无用功也就越少,如下:
SQL> select table_name, (blocks * 8192 / 1024 / 1024) - (num_rows * avg_row_len / 1024 / 1024) "data lower than hwm in mb" from user_tables  where table_name = 'T1';

TABLE_NAME      data lower than hwm in mb
--------------- -------------------------
T1                             2.59235382

查看执行计划,全表扫描大概需要消耗CPU 675
SQL> explain plan for select * from t1;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------
Plan hash value: 3617692013

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |   173K|    16M|   675   (1)| 00:00:09 |
|   1 |  TABLE ACCESS FULL| T1   |   173K|    16M|   675   (1)| 00:00:09 |
--------------------------------------------------------------------------

8 rows selected.

--删除大部分数据,收集统计信息,全表扫描依然耗cpu 673,如下:
SQL>  select count(*) from t1;

  COUNT(*)
----------
    173912

SQL> delete t1 where rownum <170000;

169999 rows deleted.

SQL> select count(*) from t1;

  COUNT(*)
----------
      3913

--使用dbms_stats分析表
SQL> exec dbms_stats.gather_table_stats('SYS','T1',CASCADE=>TRUE);

PL/SQL procedure successfully completed.

--再次查询dba_segments和dba_tables视图
SQL> select OWNER,TABLE_NAME,TABLESPACE_NAME,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,AVG_ROW_LEN,LAST_ANALYZED from dba_tables where TABLE_NAME='T1';

OWNER                          TABLE_NAME      TABLESPACE_NAME   NUM_ROWS     BLOCKS EMPTY_BLOCKS  AVG_SPACE AVG_ROW_LEN LAST_ANALYZED
------------------------------ --------------- --------------- ---------- ---------- ------------ ---------- ----------- -------------------
SYS                            T1              SYSTEM                3913       2476           83        863         101 2017-10-26 05:50:29

SQL> select OWNER,SEGMENT_NAME,TABLESPACE_NAME,BYTES,BLOCKS,EXTENTS from dba_segments where segment_name in ('T1','IDX_T1_ID');

OWNER                          SEGMENT_NAME    TABLESPACE_NAME      BYTES     BLOCKS    EXTENTS
------------------------------ --------------- --------------- ---------- ---------- ----------
SYS                            T1              SYSTEM            20971520       2560         35
SYS                            IDX_T1_ID       SYSTEM             4194304        512         19

发现dba_tables中的num_rows字段已经更新了,其他字段没有更新;而dba_segments视图相关字段也没有变化。这说明DML操作的删除行操作,即使进行了统计信息的更新,但是因为表里存在碎片,所以表大小没有变化。

--使用analyze分析表:
SQL> analyze table t1 compute statistics;

Table analyzed.

SQL> select OWNER,TABLE_NAME,TABLESPACE_NAME,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,AVG_ROW_LEN,LAST_ANALYZED from dba_tables where TABLE_NAME='T1';

OWNER                          TABLE_NAME      TABLESPACE_NAME   NUM_ROWS     BLOCKS EMPTY_BLOCKS  AVG_SPACE AVG_ROW_LEN LAST_ANALYZED
------------------------------ --------------- --------------- ---------- ---------- ------------ ---------- ----------- -------------------
SYS                            T1              SYSTEM                3913       2476           83       7761         104 2017-10-26 05:52:00

SQL> select OWNER,SEGMENT_NAME,TABLESPACE_NAME,BYTES,BLOCKS,EXTENTS from dba_segments where segment_name in ('T1','IDX_T1_ID');

OWNER                          SEGMENT_NAME    TABLESPACE_NAME      BYTES     BLOCKS    EXTENTS
------------------------------ --------------- --------------- ---------- ---------- ----------
SYS                            T1              SYSTEM            20971520       2560         35
SYS                            IDX_T1_ID       SYSTEM             4194304        512         19

还是没有变化,结论如上。。。。。。。。。。。。。。。。。

--查看执行计划,cpu cost 673几乎没变化
SQL> explain plan for select * from t1;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------
Plan hash value: 3617692013

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  3913 |   397K|   673   (1)| 00:00:09 |
|   1 |  TABLE ACCESS FULL| T1   |  3913 |   397K|   673   (1)| 00:00:09 |
--------------------------------------------------------------------------

8 rows selected.

--再次估算表在高水位线下还有多少空间是无数据的,但在全表扫描时又需要做无用功的数据块,如下:
SQL> select table_name, (blocks * 8192 / 1024 / 1024) - (num_rows * avg_row_len / 1024 / 1024) "data lower than hwm in mb" from user_tables  where table_name = 'T1';

TABLE_NAME      data lower than hwm in mb
--------------- -------------------------
T1                             18.9556503

发现表中碎片增长很多。。。。。。。。。。。。

--对表进行碎片整理,重新收集统计信息,如下:
注:碎片整理方法有:1,使用alter MOVE 表,然后索引rebuild;2.使用alter table enable row movement;然后alter table shrink space cascade(shrink使用有限制,需注意);3,通过 create table XXX as select * from abb; 4,使用导出和导入表 ;

SQL> alter table t1 disable  row movement;

Table altered.

SQL> alter  table t1 move;

Table altered.

SQL> select INDEX_NAME,STATUS from dba_indexes where index_name ='IDX_T1_ID';

INDEX_NAME                     STATUS
------------------------------ --------
IDX_T1_ID                      UNUSABLE

SQL> alter index IDX_T1_ID rebuild online;

Index altered.

--先查询dba_tables/dba_segments:
SQL>  select OWNER,TABLE_NAME,TABLESPACE_NAME,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,AVG_ROW_LEN,LAST_ANALYZED from dba_tables where TABLE_NAME='T1';

OWNER                          TABLE_NAME      TABLESPACE_NAME   NUM_ROWS     BLOCKS EMPTY_BLOCKS  AVG_SPACE AVG_ROW_LEN LAST_ANALYZED
------------------------------ --------------- --------------- ---------- ---------- ------------ ---------- ----------- -------------------
SYS                            T1              SYSTEM                3913       2476           83       7761         104 2017-10-26 05:52:00

SQL> select OWNER,SEGMENT_NAME,TABLESPACE_NAME,BYTES,BLOCKS,EXTENTS from dba_segments where segment_name in ('T1','IDX_T1_ID');

OWNER                          SEGMENT_NAME    TABLESPACE_NAME      BYTES     BLOCKS    EXTENTS
------------------------------ --------------- --------------- ---------- ---------- ----------
SYS                            T1              SYSTEM              524288         64          8
SYS                            IDX_T1_ID       SYSTEM              131072         16          2

发现经过碎片整理后且在没有收集统计信息的情况下dba_segments的块大小已经自动更新了,而dba_tables各字段没有更新

--再次查询碎片情况:
SQL> select table_name, (blocks * 8192 / 1024 / 1024) - (num_rows * avg_row_len / 1024 / 1024) "data lower than hwm in mb" from user_tables  where table_name = 'T1';

TABLE_NAME      data lower than hwm in mb
--------------- -------------------------
T1                             18.9556503

没有变化。

--收集统计信息,使用dbms_stat包:
SQL> exec dbms_stats.gather_table_stats('SYS','T1',CASCADE=>TRUE);

PL/SQL procedure successfully completed.

SQL>
SQL> select OWNER,TABLE_NAME,TABLESPACE_NAME,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,AVG_ROW_LEN,LAST_ANALYZED from dba_tables where TABLE_NAME='T1';

OWNER                          TABLE_NAME      TABLESPACE_NAME   NUM_ROWS     BLOCKS EMPTY_BLOCKS  AVG_SPACE AVG_ROW_LEN LAST_ANALYZED
------------------------------ --------------- --------------- ---------- ---------- ------------ ---------- ----------- -------------------
SYS                            T1              SYSTEM                3913         58           83       7761         101 2017-10-26 06:07:17

SQL> select OWNER,SEGMENT_NAME,TABLESPACE_NAME,BYTES,BLOCKS,EXTENTS from dba_segments where segment_name in ('T1','IDX_T1_ID');

OWNER                          SEGMENT_NAME    TABLESPACE_NAME      BYTES     BLOCKS    EXTENTS
------------------------------ --------------- --------------- ---------- ---------- ----------
SYS                            T1              SYSTEM              524288         64          8
SYS                            IDX_T1_ID       SYSTEM              131072         16          2

SQL> select table_name, (blocks * 8192 / 1024 / 1024) - (num_rows * avg_row_len / 1024 / 1024) "data lower than hwm in mb" from user_tables  where table_name = 'T1';

TABLE_NAME      data lower than hwm in mb
--------------- -------------------------
T1                             .076220512

发现经过dbms_stat包收集统计信息后dba_tables的blocks、AVG_ROW_LEN字段已经更新,且高水位下的碎片已经回收了,但是EMPTY_BLOCKS、AVG_SPACE字段没有更新

--使用analyze子句收集EMPTY_BLOCKS字段统计信息,如下;
SQL>  analyze table t1 compute statistics;

Table analyzed.

SQL> select OWNER,TABLE_NAME,TABLESPACE_NAME,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,AVG_ROW_LEN,LAST_ANALYZED from dba_tables where TABLE_NAME='T1';

OWNER                          TABLE_NAME      TABLESPACE_NAME   NUM_ROWS     BLOCKS EMPTY_BLOCKS  AVG_SPACE AVG_ROW_LEN LAST_ANALYZED
------------------------------ --------------- --------------- ---------- ---------- ------------ ---------- ----------- -------------------
SYS                            T1              SYSTEM                3913         58            5        887         104 2017-10-26 06:10:06

SQL> select OWNER,SEGMENT_NAME,TABLESPACE_NAME,BYTES,BLOCKS,EXTENTS from dba_segments where segment_name in ('T1','IDX_T1_ID');

OWNER                          SEGMENT_NAME    TABLESPACE_NAME      BYTES     BLOCKS    EXTENTS
------------------------------ --------------- --------------- ---------- ---------- ----------
SYS                            T1              SYSTEM              524288         64          8
SYS                            IDX_T1_ID       SYSTEM              131072         16          2

SQL> select table_name, (blocks * 8192 / 1024 / 1024) - (num_rows * avg_row_len / 1024 / 1024) "data lower than hwm in mb" from user_tables  where table_name = 'T1';

TABLE_NAME      data lower than hwm in mb
--------------- -------------------------
T1                              .06502533

发现经过analyze子句收集统计信息后dba_tables的EMPTY_BLOCKS、AVG_SPACE字段更新了

--再次执行sql,发现CPU cost只有17,如下:
SQL> explain plan for select * from t1;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------
Plan hash value: 3617692013

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  3913 |   397K|    17   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| T1   |  3913 |   397K|    17   (0)| 00:00:01 |
--------------------------------------------------------------------------

8 rows selected.

以上就是oracle表碎片的整理分析,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/84796.html

(0)

相关推荐

  • html如何跳转到指定页面

    技术html如何跳转到指定页面本篇内容主要讲解“html如何跳转到指定页面”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“html如何跳转到指定页面”吧!

    攻略 2021年12月10日
  • CF1167G Low Budget Inception 题解

    技术CF1167G Low Budget Inception 题解 CF1167G Low Budget Inception 题解Link.
    Codeforces
    Luogu
    Description.

    礼包 2021年10月28日
  • 如何配置web.xml中Filter的过滤器

    技术如何配置web.xml中Filter的过滤器小编给大家分享一下如何配置web.xml中Filter的过滤器,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起

    攻略 2021年11月18日
  • Matlab-两种常用绘图方式

    技术Matlab-两种常用绘图方式 Matlab-两种常用绘图方式前言
    在平时作业中经常需要对所获得的二维数据进行可视化,主要使用以下两种方法
    一、分图显示
    通过figure()划分每张图片
    x = 0

    礼包 2021年10月28日
  • 如何配置Hibernate

    技术如何配置Hibernate本篇内容主要讲解“如何配置Hibernate”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何配置Hibernate”吧!当我们有了一个持久化类

    攻略 2021年12月4日
  • mysql从共享表空间修改为单个表的表空间存储方式是什么

    技术mysql从共享表空间修改为单个表的表空间存储方式是什么本篇文章为大家展示了mysql从共享表空间修改为单个表的表空间存储方式是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收

    攻略 2021年11月16日