DBMS_SPACE包的使用
最近有朋友问到了DBMS_SPACE包的使用,也看了一下,大部分是关于dbms_space.space_usage的使用,space_usage这个过程的例子已经很多了,我也就不再多说了,除了这个过程外,另外还有两个过程也有着特殊的用处,但使用的人不多,我们也来看看这两个过程有什么用。
这两个过程为:CREATE_INDEX_COST和CREATE_TABLE_COST,分别用户评估创建索引和创建表的存储开销(空间占用情况)。
CREATE_INDEX_COST的语法如下:
DBMS_SPACE.CREATE_INDEX_COST (
ddl IN VARCHAR2,
used_bytes OUT NUMBER,
alloc_bytes OUT NUMBER,
plan_table IN VARCHAR2 DEFAULT NULL);
1、准备相关表和数据
SQL> set serveroutput on
SQL> create table t(c char(100),d varchar2(200));
表已创建。
SQL> begin
2 for i in 1..5000 loop
3 insert into t values(i,i);
4 end loop;
5 commit;
6 end;
7 /
PL/SQL过程已成功完成。
2、分析表,注意:没有统计信息,CREATE_INDEX_COST将无法计算索引的存储开销
SQL> analyze table t compute statistics;
表已分析。
SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(c)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
488.28125 640 --计算出的索引将占用488K字节空间,为该索引需要分配640k存储空间
PL/SQL过程已成功完成。
3、创建实际索引,确定索引存储空间是否与计算的结果相符
SQL> create index i on t(c);
索引已创建。
SQL> select count(*) from user_extents where segment_name='I';
COUNT(*)
----------
11
已选择1行。 --11个64k的区,比计算出的大1个区
4、再次装载数据
SQL> begin
2 for i in 1..5000 loop
3 insert into t values(i,i);
4 end loop;
5 commit;
6 end;
7 /
PL/SQL过程已成功完成。
SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(c)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
488.28125 640 --没有分析之前,获得得仍然是根据以前分析结果计算的值
PL/SQL过程已成功完成。
SQL> analyze table t compute statistics;
表已分析。
SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(c)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
976.5625 2048 --分析之后,得到新的结果
PL/SQL过程已成功完成。
5、再次验证,16个64k的区和1个1024k的区,2048k,与估计值相同
SQL> select count(*) from user_extents where segment_name='I';
COUNT(*)
----------
17
-------------------------------------------------------------
6、换了一个字段进行测试
SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(d)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
39.0625 192 --计算出的索引将占用39K字节空间,为该索引需要分配192k存储空间
PL/SQL过程已成功完成。
7、创建索引,新建的索引比估算的值大1个区
SQL> create index i on t(d);
索引已创建。
SQL> select count(*) from user_extents where segment_name='I';
COUNT(*)
----------
4
SQL> drop index i;
8、再次装载数据并分析表
SQL> begin
2 for i in 1..10000 loop
3 insert into t values(i,i);
4 end loop;
5 commit;
6 end;
7 /
PL/SQL过程已成功完成。
SQL> analyze table t compute statistics;
表已分析。
9、重新计算,得到新的估算值
SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(d)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
78.125 320
PL/SQL过程已成功完成。
10、创建索引,新建的索引比估计的大2个区
SQL> create index i on t(d);
索引已创建。
SQL> select count(*) from user_extents where segment_name='I';
COUNT(*)
----------
7
11、顺便测试shink space的效果
SQL> select count(*) from t;
COUNT(*)
----------
20000
SQL> delete t where rownum<=15000;
已删除15000行。
SQL> commit;
提交完成。
SQL> alter table t enable row movement;
表已更改。
12、在删掉15000行数据后,没有整理空间之前进行统计信息收集
SQL> analyze table t compute statistics;
表已分析。
SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(d)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
24.4140625 128 --基于新收集的统计信息计算,估算的索引需要分配128k存储空间
PL/SQL过程已成功完成。
13、收缩表,释放占用的存储空间
SQL> alter table t shrink space;
表已更改。
SQL> analyze table t compute statistics;
表已分析。
SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(d)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
24.4140625 128 --收缩后重新收集统计信息,与原统计信息一样,因此计算出的大小一样
PL/SQL过程已成功完成。
SQL> select count(*) from user_extents where segment_name='I';
COUNT(*)
----------
7
--现有索引并没有收缩,仅仅是表空间进行了收缩,因此现有索引仍保持原大小
14、重建索引,对比新的索引大小与计算出的索引大小一样大
SQL> alter index i rebuild;
索引已更改。
SQL> select count(*) from user_extents where segment_name='I';
COUNT(*)
----------
2
--重建索引后新的索引占用空间与计算出的空间一样大
CREATE_TABLE_COST有两种用法,因此包内进行了overload,具体的语法如下:
DBMS_SPACE.CREATE_TABLE_COST (
tablespace_name IN VARCHAR2,
avg_row_size IN NUMBER,
row_count IN NUMBER,
pct_free IN NUMBER,
used_bytes OUT NUMBER,
alloc_bytes OUT NUMBER);
DBMS_SPACE.CREATE_TABLE_COST (
tablespace_name IN VARCHAR2,
colinfos IN CREATE_TABLE_COST_COLUMNS,
row_count IN NUMBER,
pct_free IN NUMBER,
used_bytes OUT NUMBER,
alloc_bytes OUT NUMBER);
CREATE TYPE create_table_cost_colinfo IS OBJECT (
COL_TYPE VARCHAR(200),
COL_SIZE NUMBER);
1、测试创建一个表所需的存储大小,预计该表平均行长度为100字节,10000行数据
SQL> DECLARE
2 V1 NUMBER;
3 V2 NUMBER;
4 BEGIN
5 DBMS_SPACE.CREATE_TABLE_COST('USERS', 100, 10000, 10, V1, V2);
6 DBMS_OUTPUT.PUT_LINE('V1: '||V1/1024/8||' V2: '||V2/1024/8);
7 END;
8 /
V1: 143 V2: 256 --估算出该表需要存储空间143块,所需分配空间256块
PL/SQL过程已成功完成。
2、创建该表,并插入10000行数据
SQL> CREATE TABLE T1(C CHAR(96)); --96字节的char字段平均行长度为100字节
表已创建。
SQL> BEGIN
2 FOR I IN 1..10000 LOOP
3 INSERT INTO T1 VALUES(I);
4 ENDLOOP;
5 COMMIT;
6 END;
7 /
PL/SQL过程已成功完成。
3、分析表统计信息
SQL> ANALYZE TABLE T1 COMPUTE STATISTICS;
表已分析。
SQL> SELECT BLOCKS,EMPTY_BLOCKS,AVG_ROW_LEN
FROM USER_TABLES WHERE TABLE_NAME='T1';
BLOCKS EMPTY_BLOCKS AVG_ROW_LEN
---------- ------------ -----------
180 76 100
--经检查,高水平线之前的块数180块,高水平线之后的空块数76块,总存储空间为256块,与DBMS_SPACE.CREATE_INDEX_COST计算出的总需要存储空间大小相符。
4、通过dbms_space.space_usage过程,可以进一步看到表中各个块的使用情况
declare
unf number;
unfb number;
fs1 number;
fs1b number;
fs2 number;
fs2b number;
fs3 number;
fs3b number;
fs4 number;
fs4b number;
full number;
fullb number;
own dba_tables.owner%type;
tab dba_tables.table_name%type;
yesno varchar2(3);
type parts is table of dba_tab_partitions%rowtype;
partlist parts;
type cursor_ref is ref cursor;
c_cur cursor_ref;
begin
own:=upper('&owner');
tab:=upper('&table_name');
dbms_output.put_line('--------------------------------------------------------------------------------');
open c_cur for select partitioned from dba_tables
where wner=own and table_name=tab;
fetch c_cur into yesno;
close c_cur;
dbms_output.put_line('Owner: '||own);
dbms_output.put_line('Table: '||tab);
dbms_output.put_line('------------------------------------------------');
if yesno='NO' then
dbms_space.space_usage(own,tab,'TABLE',unf,unfb,fs1,fs1b,fs2,fs2b,fs3,fs3b,fs4,fs4b,full,fullb);
dbms_output.put_line('unf: '||unf||' fs1: '||fs1||' fs2: '||fs2||' fs3: '||fs3||' fs4: '||fs4||' full: '||full);
else
open c_cur for select * from dba_tab_partitions
where table_owner=own and table_name=tab;
fetch c_cur bulk collect into partlist;
close c_cur;
for i in partlist.first .. partlist.last loop
dbms_space.space_usage(partlist(i).table_owner,partlist(i).table_name,'TABLE
PARTITION',unf,unfb,fs1,fs1b,fs2,fs2b,fs3,fs3b,fs4,fs4b,full,fullb,partlist(i).partition_name);
dbms_output.put_line('Partition: '||partlist(i).partition_name);
dbms_output.put_line('unf: '||unf||' fs1: '||fs1||' fs2: '||fs2||' fs3: '||fs3||' fs4: '||fs4||' full: '||full);
end loop;
end if;
dbms_output.put_line('--------------------------------------------------------------------------------');
end;
/
输入owner的值: HR
原值 22: own:=upper('&owner');
新值 22: own:=upper('HR');
输入table_name的值: T1
原值 23: tab:=upper('&table_name');
新值 23: tab:=upper('T1');
--------------------------------------------------------------------------------
Owner: HR
Table: T1
------------------------------------------------
unf: 0 fs1: 1 fs2: 0 fs3: 0 fs4: 39 full: 140
--------------------------------------------------------------------------------
PL/SQL过程已成功完成。
--经查看,发现该表写满数据的块有140块,3/4满的块有39块,1/4满的块有1块,该表存储空间没有有效利用,可以看到140+39+1=180,这些均为高水平线之下的块。但与DBMS_SPACE.CREATE_INDEX_COST计算出的数据需要143块不符。
5、对表进行空间整理并重新分析
SQL> ALTER TABLE T1 MOVE;
表已更改。
SQL> ANALYZE TABLE T1 COMPUTE STATISTICS;
表已分析。
SQL> SELECT BLOCKS,EMPTY_BLOCKS,AVG_ROW_LEN
FROM USER_TABLES WHERE TABLE_NAME='T1';
BLOCKS EMPTY_BLOCKS AVG_ROW_LEN
---------- ------------ -----------
155 101 100
--经检查,高水平线之前的块数155,高水平线之后的空块数101,平均行长度100字节
6、通过dbms_space.space_usage过程,可以进一步看到表中各个块的使用情况
declare
unf number;
unfb number;
fs1 number;
fs1b number;
fs2 number;
fs2b number;
fs3 number;
fs3b number;
fs4 number;
fs4b number;
full number;
fullb number;
own dba_tables.owner%type;
tab dba_tables.table_name%type;
yesno varchar2(3);
type parts is table of dba_tab_partitions%rowtype;
partlist parts;
type cursor_ref is ref cursor;
c_cur cursor_ref;
begin
own:=upper('&owner');
tab:=upper('&table_name');
dbms_output.put_line('--------------------------------------------------------------------------------');
open c_cur for select partitioned from dba_tables
where wner=own and table_name=tab;
fetch c_cur into yesno;
close c_cur;
dbms_output.put_line('Owner: '||own);
dbms_output.put_line('Table: '||tab);
dbms_output.put_line('------------------------------------------------');
if yesno='NO' then
dbms_space.space_usage(own,tab,'TABLE',unf,unfb,fs1,fs1b,fs2,fs2b,fs3,fs3b,fs4,fs4b,full,fullb);
dbms_output.put_line('unf: '||unf||' fs1: '||fs1||' fs2: '||fs2||' fs3: '||fs3||' fs4: '||fs4||' full: '||full);
else
open c_cur for select * from dba_tab_partitions
where table_owner=own and table_name=tab;
fetch c_cur bulk collect into partlist;
close c_cur;
for i in partlist.first .. partlist.last loop
dbms_space.space_usage(partlist(i).table_owner,partlist(i).table_name,'TABLE
PARTITION',unf,unfb,fs1,fs1b,fs2,fs2b,fs3,fs3b,fs4,fs4b,full,fullb,partlist(i).partition_name);
dbms_output.put_line('Partition: '||partlist(i).partition_name);
dbms_output.put_line('unf: '||unf||' fs1: '||fs1||' fs2: '||fs2||' fs3: '||fs3||' fs4: '||fs4||' full: '||full);
end loop;
end if;
dbms_output.put_line('--------------------------------------------------------------------------------');
end;
/
输入owner的值: HR
原值 22: own:=upper('&owner');
新值 22: own:=upper('HR');
输入table_name的值: T1
原值 23: tab:=upper('&table_name');
新值 23: tab:=upper('T1');
--------------------------------------------------------------------------------
Owner: HR
Table: T1
------------------------------------------------
unf: 0 fs1: 0 fs2: 0 fs3: 0 fs4: 0 full: 143
--------------------------------------------------------------------------------
PL/SQL过程已成功完成。
--经查看,发现该表写满数据的块有143块,与DBMS_SPACE.CREATE_INDEX_COST计算出的数据需要块数完全相同
-- review the parameters
SELECT argument_name, data_type, type_owner, type_name
FROM all_arguments
WHERE object_name = 'CREATE_TABLE_COST'
AND verload = 2
-- examine the input parameter type
SELECT text
FROM dba_source
WHERE name = 'CREATE_TABLE_COST_COLUMNS';
-- drill down further into the input parameter type
SELECT text
FROM dba_source
WHERE name = 'create_table_cost_colinfo';
set serveroutput on
DECLARE
ub NUMBER;
ab NUMBER;
cl sys.create_table_cost_columns;
BEGIN
cl := sys.create_table_cost_columns( sys.create_table_cost_colinfo('NUMBER',10),
sys.create_table_cost_colinfo('VARCHAR2',30),
sys.create_table_cost_colinfo('VARCHAR2',30),
sys.create_table_cost_colinfo('DATE',NULL));
DBMS_SPACE.CREATE_TABLE_COST('SYSTEM',cl,100000,0,ub,ab);
DBMS_OUTPUT.PUT_LINE('Used Bytes: ' || TO_CHAR(ub));
DBMS_OUTPUT.PUT_LINE('Alloc Bytes: ' || TO_CHAR(ab));
END;
/
http://blog.csdn.net/liqfyiyi/article/details/7036838
DBMS_SPACE包的使用的更多相关文章
- 十五、dbms_space(分析段增长和空间的需求)
1.概述 作用:用于分析段增长和空间的需求. 2.包的组成 1).unused_space作用:用于返回对象(表.索引.簇)的未用空间语法:dbms_space.unused_space(segmen ...
- Npm包的开发
个人开发包的目录结构 ├── coverage //istanbul测试覆盖率生成的文件 ├── index.js //入口文件 ├── introduce.md //说明文件 ├── lib │ ...
- Windows server 2012 添加中文语言包(英文转为中文)(离线)
Windows server 2012 添加中文语言包(英文转为中文)(离线) 相关资料: 公司环境:亚马孙aws虚拟机 英文版Windows2012 中文SQL Server2012安装包,需要安装 ...
- 如何在nuget上传自己的包+搭建自己公司的NuGet服务器(新方法)
运维相关:http://www.cnblogs.com/dunitian/p/4822808.html#iis 先注册一个nuget账号https://www.nuget.org/ 下载并安装一下Nu ...
- android http 抓包
有时候想开发的时候想看APP发出的http请求和响应是什么,这就需要抓包了,这可以得到一些不为人知的api,比如还可以干些“坏事”... 需要工具: Fiddler2 抓包(点击下载) Android ...
- 带你实现开发者头条APP(四)---首页优化(加入design包)
title: 带你实现开发者头条APP(四)---首页优化(加入design包) tags: design,Toolbar,TabLayout,RecyclerView grammar_cjkRuby ...
- git克隆项目到本地&&全局安装依赖项目&&安装依赖包&&启动服务
一.安装本地开发环境 1.安装本项目 在需要保存到本地的项目的文件夹,进入到文件夹里点击右键,bash here,出现下图: 2.安装依赖项目 3.安装依赖包(进入到命令行) # 安装依赖包 $ ...
- 关于Visual Studio 未能加载各种Package包的解决方案
问题: 打开Visual Studio 的时候,总提示未能加载相应的Package包,有时候还无法打开项目,各种提示 解决方案: 进入用户目录 C:\Users\用户名\AppData\Local\M ...
- VS项目中使用Nuget还原包后编译生产还一直报错?
Nuget官网下载Nuget项目包的命令地址:https://www.nuget.org/packages 今天就遇到一个比较奇葩的问题,折腾了很久终于搞定了: 问题是这样的:我的解决方案原本是好好的 ...
随机推荐
- springboot 异常: Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-07-31 11:56:18.812 WARN 10316 --- [ main] ConfigServletWebServerApplicationContext : Exception ...
- 92. extjs specialkey监听回车按键
转自:http://blog.sina.com.cn/s/blog_647a022e0101401n.html 1 监听表单字段事件: Ext使得对用户某个动作的监听特别简单,诸如单击某个元素或者按下 ...
- Coursera Algorithms week2 基础排序 练习测验: Permutation
题目原文: Given two integer arrays of size n , design a subquadratic algorithm to determine whether one ...
- Gym - 101981K The 2018 ICPC Asia Nanjing Regional Contest K.Kangaroo Puzzle 暴力或随机
题面 题意:给你1个20*20的格子图,有的是障碍有的是怪,你可以每次指定上下左右的方向,然后所有怪都会向那个方向走, 如果2个怪撞上了,就融合在一起,让你给不超过5w步,让所有怪都融合 题解:我们可 ...
- selenium3 + python - xpath定位
什么是xpath呢? 官方介绍:XPath即为XML路径语言,它是一种用来确定XML1(标准通用标记语言3的子集)文档中某部分位置的语言.反正小编看这个介绍是云里雾里的,通俗一点讲就是通过元素的路径来 ...
- Java.HttpClient绕过Https证书解决方案二
方案2 import java.io.*; import java.net.URL; import java.net.URLConnection; import java.security.Secur ...
- 笔记《javascript高级程序设计》 第12章 DOM2和DOM3
DOM2 级核心:在 1 级基础上构建,为节点添加更多方法和属性 DOM2 级视图:为文档定义了基于样式信息的不同视图 DOM2 级事件:说明了如何使用事件和DOM文档交互 DOM2 级样式:如何以编 ...
- ThreadLocal类详解
学习一个东西首先要知道为什么要引入它,就是我们能用它来干什么.所以我们先来看看ThreadLocal对我们到底有什么用,然后再来看看它的实现原理. ThreadLocal如果单纯从名字上来看像是“本地 ...
- php解析 html类库 simple_html_dom
如果从字符串加载html文档,需要先从网络上下载.建议使用cURL来抓取html文档并加载DOM中. 查找html元素 可以使用find函数来查找html文档中的元素.返回的结果是一个包含了对象的数组 ...
- 阿里云 CentOS 6.5 使用XAMPP 搭建LAMP环境
LAMP环境是常见的服务器环境,也是PHP网站常用的服务器环境,很多人喜欢手动配置,但是手动配置LAMP复杂.麻烦,简单一点的话可以使用集成环境.试了下LNMP的集成环境,用不习惯,另外由于本地一直使 ...