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需要跟当前表一样大小的空闲空间。

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

  1. WPF根据Oracle数据库的表,生成CS文件小工具

    开发小工具的原因: 1.我们公司的开发是客户端用C#,服务端用Java,前后台在通讯交互的时候,会用到Oracle数据库的字段,因为服务器端有公司总经理开发的一个根据Oracle数据库的表生成的cla ...

  2. 定时从远程的数据库中取数据,然后把取出来的数据插入或更新本地的oracle数据库的表

    最近项目中有一种需求: 大致需求是这样的 通过给定的 用户名和密码 要定时从远程的数据库中取数据,然后把取出来的数据插入或更新本地的oracle数据库的表 项目的结构式struts1 hibernat ...

  3. 使用OPTIMIZE TABLE命令来整理表碎片实践

    操作环境:ubuntu 14.10   mysql 5.6.25 对含有BLOB或TEXT字段的表,若经常做修改或删除类的操作,需要定期执行OPTIMIZE TABLE命令来整理碎片. 1.creat ...

  4. PowerDesigner连接Oracle数据库建表序列号实现自动增长

    原文:PowerDesigner连接Oracle数据库建表序列号实现自动增长 创建表就不说了.下面开始介绍设置自动增长列. 1 在表视图的列上创建.双击表视图,打开table properties — ...

  5. Oracle数据库创建表是有两个约束带有默认索引

    Oracle数据库创建表是有两个约束带有默认索引.1.主键primary Key:唯一索引.非空2.唯一Unique:唯一索引,可以是空值如果没有设定主键和唯一约束,表中不会有默认索引的. 建立主键/ ...

  6. 链接oracle数据库 生成表对应的javabean

    package com.databi.utils; import java.io.File; import java.io.FileOutputStream; import java.io.IOExc ...

  7. Oracle 删除用户和表空间////Oracle创建删除用户、角色、表空间、导入导出、...命令总结/////Oracle数据库创建表空间及为用户指定表空间

    Oracle 使用时间长了, 新增了许多user 和tablespace. 需要清理一下 对于单个user和tablespace 来说, 可以使用如下命令来完成. 步骤一:  删除user drop ...

  8. ORACLE 数据库及表信息

    查看ORACLE 数据库及表信息   -- 查看ORACLE 数据库中本用户下的所有表 SELECT table_name FROM user_tables; -- 查看ORACLE 数据库中所有用户 ...

  9. Oracle数据库查看表空间sql语句

    转: Oracle数据库查看表空间sql语句 2018-09-03 15:49:51 兰海泽 阅读数 6212   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出 ...

随机推荐

  1. HTML+CSS入门

    <strong>加粗</strong> <em>斜体</em> <p>段落</p> <span>设置单独样式< ...

  2. STL中的单向队列queue

    转载自:http://blog.csdn.net/morewindows/article/details/6950917 stl中的queue指单向队列,使用时,包含头文件<queue>. ...

  3. 循环队列实现(C++) Ring Buffer

    循环队列:队列有着先入先出的特性.但是对于队列如果删除队头以后剩下的空间将不会被释放,又由于队列只能由队尾插入这就导致被删除部分的空间被浪费.解决这个问题就是循环队列.循环队列顾名思义就是将队列串起来 ...

  4. 01-04-02【Nhibernate (版本3.3.1.4000) 出入江湖】HQL查询

    public IList<Customer> GetAllHql() { IList<Customer> result = null; ISession session = _ ...

  5. Unity3D Log 收集机制

    最近做项目的时候发现,需要有一个完整的log机制.这样不仅方便调试而且方便观察. 一.需求 目前我认为一个完善的log机制应该是这样的. 一.双击定位 二.生命周期是全局的 三.输出包括consloe ...

  6. Installing Lua in Mac

    Lua is distributed in source form. You need to build it before using it. Building Lua should be stra ...

  7. hdu 1253 胜利大逃亡(广搜,队列,三维,简单)

    题目 原来光搜是用队列的,深搜才用栈,我好白痴啊,居然搞错了 三维的基础的广搜题 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #in ...

  8. java实现大数加法、乘法(BigDecimal)

    之前写过用vector.string实现大数加法,现在用java的BigDecimal类,代码简单很多.但是在online-judge上,java的代码运行时间和内存大得多. java大数加法:求a+ ...

  9. 去掉eclipse的xml和js验证

    一.XML Properties > Validation you have two options: 1- Configure Workspace Settings (disable the ...

  10. log4j的基本配置参数

    转载:http://blog.csdn.net/fengyifei11228/article/details/6070006 log4j配置文件有三个主要的组件:Logger,Appender和Lay ...