Oracle 数据库整理表碎片

Oracle 数据库整理表碎片

转载:http://kyle.xlau.org/posts/table-fragmentation.html

表碎片的来源

当针对一个表的删除操作很多时,表会产生大量碎片。删除操作释放的空间不会被插入操作立即重用,甚至永远也不会被重用。

怎样确定是否有表碎片

-- 收集表统计信息
SQL> exec dbms_stats.gather_table_stats(ownname=>‘SCHEMA_NAME‘,tabname=> ‘TABLE_NAME‘);

-- 确定碎片程度
SQL> SELECT table_name, ROUND ((blocks * 8), 2) "高水位空间 k",
   ROUND ((num_rows * avg_row_len / 1024), 2) "真实使用空间 k",
   ROUND ((blocks * 10 / 100) * 8, 2) "预留空间(pctfree) k",
   ROUND ((  blocks * 8
           - (num_rows * avg_row_len / 1024)
           - blocks * 8 * 10 / 100
          ),
          2
         ) "浪费空间 k"
  FROM dba_tables
  WHERE table_name = ‘TABLE_NAME‘;

或者使用如下gist中的脚本找出某个 Schema 中表碎片超过25%的表。使用此脚本前,先确定 Schema 中表统计信息收集完整。

-- 查看表上次收集统计信息时间
select table_name,last_analyzed from dba_tables where owner = ‘SCHEMA_NAME‘

-- 收集整个 Schema 中对象的统计信息
SQL> exec dbms_stats.gather_schema_stats(ownname=>‘SCHEMA_NAME‘);

为什么要整理表碎片

Oracle 对数据段的管理有一个高水位(HWM, High Water Mark)的概念。高水位是数据段中使用过和未使用过的数据块的分界线。高水位以下的数据块是曾使用过的,以上的是从未被使用或初始化过的。

当 Oracle 进行全表扫描(FTS, Full table scan)的操作时,它会读高水位下的所有数据块。如果高水位下还有很多空闲空间(碎片),读取这些空闲数据块会降低操作的性能。

行链接和行迁移

  • 行链接 Row Chaining:当插入数据量大的行的,如果一个Block不能存放一条 记录,该记录的一部分会存储到同个Extent中的其他Block,这些block形成一 个数据块链。
  • 行迁移 Row Migration:当Update的时候导致记录长度增加了,存储的Block已 经满了,就会发生行迁移。Oracle会迁移整行数据到一个能够存储下整行数据 的Block中,迁移的原始指针指向新的存放行数据的Block,ROWID不变。

当数据行发生链接(chain)或迁移(migrate)时,对其访问将会造成 I/O 性能 降低,因为Oracle为获取这些数据行的数据,必须访问更多的数据块(data block)。

表碎片导致的问题

  • 查询响应时间(尤其是全表扫描)变慢
  • 产生大量行迁移
  • 浪费空间

整理表碎片对基于索引的查询不会有太大性能提升。

如何整理表碎片

10g之前

两种方法:

  • 导出表,删除表,再导入表
  • alter table move

一般选择第二种,需要重建索引。

10g后

从 10g 开始,提供一个 shrink 命令,需要表空间是基于自动段管理的。

可以分成两步操作:

-- 整理表,不影响DML操作
SQL> alter table TABLE_NAME shrink space compact;

-- 重置高水位,此时不能有DML操作
SQL> alter table TABLE_NAME shrink space;

也可以一步到位:

-- 整理表,并重置高水位
SQL> alter table TABLE_NAME shrink space;

shrink 的优势:

  • 不需要重建索引。
  • 可以在线操作。
  • 不需要空闲空间,alter move需要跟当前表一样大小的空闲空间。

来自为知笔记(Wiz)

时间: 2024-12-19 17:53:19

Oracle 数据库整理表碎片的相关文章

Oracle数据库创建表空间

--Oracle数据库创建表空间 create tablespace new_taspace --表空间名 DATAFILE 'D:\NEWTABLESPACE.DBF'   --表空间关联的数据文件和位置 size 200M --文件初始大小 autoextend on next 20MB MAXSIZE 400MB; --文件大小可自动扩展,每次扩展20MB,最大400MB --创建表空间 create tablespace new_taspace1 --表空间关联的数据文件和位置 DATA

C#获取oracle数据库某表的列名和数据类型【转载】

C#获取oracle数据库某表的列名和数据类型的sql语句为: select column_name,data_type ,data_length,data_precision,data_scale from user_tab_columns [where table_name=表名] 关于此sql语句的说明: column_name:某表列名(varchar2(30)); data_type:某表列的数据类型(varchar2(106)); data_length:某表列的长度(number)

Linux oracle数据库创建表空间、用户并赋予权限

管理员用户登录oracle数据库 1.创建临时表空间 select name from v$tempfile;查出当前数据库临时表空间,主要是使用里面的存放路径: 得到其中一条记录/opt/oracle/oradata/orcl/temp01.dbf 创建临时表空间:create temporary tablespace plncontrol_temp tempfile '/opt/oracle/oradata/orcl/plncontrol_temp.dbf' size 100m reuse

查看ORACLE 数据库及表信息

-- 查看ORACLE 数据库中本用户下的所有表 SELECT table_name FROM user_tables; -- 查看ORACLE 数据库中所有用户下的所有表 select user,table_name from all_tables; -- 查看ORACLE 数据库中本用户下的所有列 select table_name,column_name from user_tab_columns; -- 查看ORACLE 数据库中本用户下的所有列 select user,table_na

oracle数据库的表的操作

今天,学习oracle数据库中数据库的创建和表的创建删除修改等等操作.开始的时候,数据库一直连接不上,后来知道原来是几个服务没有开启:OracleXETNSListener,OracleXEClrAgent,OracleServiceXE.参考网址:http://jingyan.baidu.com/article/3d69c5518f2de2f0ce02d747.html 我发现有些大学时候学习sql语句,有的并不适用oracle数据库.下面是我实践中用到的: --创建外键1 CREATE TA

Oracle数据库锁表查询以及解锁进程

Oracle数据库操作中,我们有时会用到锁表查询以及解锁和kill进程等操作,那么这些操作是怎么实现的呢?本文我们主要就介绍一下这部分内容. 锁表查询的代码有以下的形式: select count(*) from v$locked_object; select * from v$locked_object; 查看哪个表被锁 1.select b.owner,b.object_name,a.session_id,a.locked_mode 2. from v$locked_object a,dba

oracle数据库创建表且主键自增

Oracle数据库中,设置ID自增并不像MySQL中那么简单,Oracle中需要设置一个序列. 现在给出方式,具体如下: 第一步:建立一个表 create table ContestDB ( TID NUMBER(10) PRIMARY KEY, TEAMNUM varchar(50) not null, MARKNUM varchar(50) ); 第二步:设置ID自增 第一种方式:不使用触发器 1 CREATE SEQUENCE SEQ_TID; 2 INSERT INTO ContestD

Oracle数据库的表空间基本管理

一.概述 Oracle数据库是通过表空间来存储物理表的,一个数据库实例可以有N个表空间,一个表空间下可以有N张表. 有了数据库,就可以创建表空间. 表空间(tablespace)是数据库的逻辑划分,每个数据库至少有一个表空间(称作SYSTEM表空间).为了便于管理和提高运行效率,可以使用一些附加表空间来划分用户和应用程序.例如:USER表空间供一般用户使用,RBS表空间供回滚段使用.一个表空间只能属于一个数据库. 表空间是数据库中最大的逻辑单位, SYSTEM和SYSAUX表空间是在创建数据库时

oracle数据库创建表

实际工作中,在数据库中创建表是经常会用到的.我们今天呢?主要给大家来分享一下在数据库如何通过sql语句去创建表.其实,创建表很简单,只需要把数据库的数据类型和约束搞清楚就可以了,其他的就好说了.接下来呢,开始我的表演.首先,先使用plsql连接到oracle数据库,先保证下面的服务是开启的. 我们本次创建表的需求是:创建一张班级表,和一张学生表. 1.首先班级表作为主表也就是所谓的主键.在主表中我们这里使用的约束是primarykey 和not null  (当然不局限于这些) create t