热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

记录一次大表分区引起存储空间膨胀使用的问题

建立数值类型列为分区键的

有这样一个表A(id number(10,0), bid number(10,0),userid varchar2(20),dat1 timestamp,group_id number(10,0);

上面有8亿数据,47G左右,表上没有任何索引,平常处理数据都是使用group_id来过滤,group_id有15000个左右,每年增长几千个。

我们知道oracle分区表最多支持1048575个分区,每年增长几千个,需要100年才会达到上限,因此我们确定的分区方案是按group_id作为分区键,做间隔为1的间隔分区表。

 

结果是我们把数据迁移到分区表后,发现分区表占用空间达到了160G,比原来大了2倍多,差点儿把表空间给撑到告警,有点儿心惊胆战,事后对此事做个总结:

为什么空间会比非分区表大那么多,原因是忽略了分区表默认分区大小。

Oracle11G新特性:分区表分区默认segment大小64k变为8M

从11.2.0.2开始创建分区表,每个分区默认大小为8M,是由_partition_large_extents参数控制,可以算是11.2.0.2开始的一个新特性,为了减少extent数量,提高分区表性能,而引入的一个参数,默认为true,即分区表的每个extent为8M。

如果分区键列上数据分布有倾斜,那数据量少的分区上将会造成很大的空间浪费,试想8M的空间上只存储几条数据,如果有5000个分区这样,那会浪费多大的空间。

同样地索引分区受参数_index_partition_large_extents的控制,而当_index_partition_large_extents为true时,创建分区索引时,默认分区大小为8m,而创建普通索引默认大小为64k。_index_partition_large_extents默认为false。

因此在以数值类型的列作为分区键时,在计划做成间隔分区时,需要考虑以下因素:

1. 查询3个参数的设置:

(1)查询_partition_large_extents、_index_partition_large_extents的设置,这两个参数为隐藏参数,查询脚本如下:

SELECT i.ksppinm name, CV.ksppstvl VALUE

  FROM sys.x$ksppi i, sys.x$ksppcv CV

 WHERE i.inst_id = USERENV('Instance')

   AND CV.inst_id = USERENV('Instance')

   AND i.indx = CV.indx

   AND i.ksppinm in

       ('_partition_large_extents', '_index_partition_large_extents');

(2)查询参数deferred_segment_creation

这个参数为延迟段创建,如果为true,表示创建表的分区时,如果该分区不插入数据,将不会分配段空间。

2. 如果_partition_large_extents、_index_partition_large_extents均为true,要考虑该分区键值得分布。如果存在倾斜,建议创建表时指定storage 属性,默认分区大小设置小点儿。如果数据量比较大,且分布比较均匀,可以使用默认设置。

创建分区表指定storage属性参考如下:

SCOTT@PROD1>create table t1220(id number(10),col1 varchar2(20),group_id number(10))

   storage (initial 64k next 1m)

   partition by range(group_id)

   interval (1)

  (partition p12200 values less than (0),

  partition p12201 values less than (4) );

 

Table created.

 

SCOTT@PROD1>select segment_name,partition_name,bytes/1024 kb,blocks from user_segments where segment_name='T1220';

 

no rows selected

SCOTT@PROD1>insert into t1220 values(1,'aa',5);

 

1 row created.

 

SCOTT@PROD1>commit;

 

Commit complete.

 

SCOTT@PROD1>select segment_name,partition_name,bytes/1024 kb,blocks from user_segments where segment_name='T1220';

 

SEGMENT_NAME         PARTITION_NAME                      KB        BLOCKS

--------------------          ------------------------------ -                 ---------      ----------

T1220                SYS_P141                               64          8

 

发现插入一条数据后,段分配的第一个extent,有8个块,占64KB的空间。

 

当然建表时没有指定storage属性,表建成后也是可以修改默认属性的。

SCOTT@PROD1>alter table t1220 modify default attributes storage (initial 128k next 1m);

 

Table altered.

 

SCOTT@PROD1>insert into t1220 values(2,'bb',6);

 

1 row created.

 

SCOTT@PROD1>commit;

 

Commit complete.

 

SCOTT@PROD1>select segment_name,partition_name,bytes/1024 kb,blocks from user_segments where segment_name='T1220';

 

SEGMENT_NAME         PARTITION_NAME                         KB     BLOCKS

-------------------- ------------------------------ ---------- ----------

T1220                SYS_P141                               64          8

T1220                SYS_P142                              128         16

 

对于日期类型列为分区键,如果按月分区,总分区数也比较有限,可以不用考虑太多,而且一般这种分区方式数据分布也比较均匀。

另外:SYS用户下对象是不支持延迟段功能的。

SYS@PROD1>create table t1220_1(id number(10),col1 varchar2(20),group_id number(10))

  2  storage (initial 64k next 1m)

  3  partition by range(group_id)

  4  interval (1)

  5  (partition p122010 values less than (0) segment creation deferred,

  6   partition p122011 values less than (4) segment creation deferred

  7  );

create table t1220_1(id number(10),col1 varchar2(20),group_id number(10))

*

ERROR at line 1:

ORA-14223: Deferred segment creation is not supported for this table

 

 

 

 

 


推荐阅读
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 本文详细介绍了Java反射机制的基本概念、获取Class对象的方法、反射的主要功能及其在实际开发中的应用。通过具体示例,帮助读者更好地理解和使用Java反射。 ... [详细]
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • 本文详细介绍了在 Oracle 数据库中使用 MyBatis 实现增删改查操作的方法。针对查询操作,文章解释了如何通过创建字段映射来处理数据库字段风格与 Java 对象之间的差异,确保查询结果能够正确映射到持久层对象。此外,还探讨了插入、更新和删除操作的具体实现及其最佳实践,帮助开发者高效地管理和操作 Oracle 数据库中的数据。 ... [详细]
  • DirectShow Filter 开发指南
    本文总结了 DirectShow Filter 的开发经验,重点介绍了 Source Filter、In-Place Transform Filter 和 Render Filter 的实现方法。通过使用 DirectShow 提供的类,可以简化 Filter 的开发过程。 ... [详细]
  • 近期在开发的一个项目中,预计数据量将在半年内突破千万条。为了提高查询性能,减少数据处理时间,我们决定采用Oracle数据库的分区功能。本文将详细介绍Oracle的List分区及其索引策略。 ... [详细]
  • 本文详细介绍了MySQL故障排除工具及其使用方法,帮助开发者和数据库管理员高效地定位和解决数据库性能问题。 ... [详细]
  • 图数据库与传统数仓实现联邦查询使用CYPHER实现从关系数据库过滤时间序列指标一、MySQL得到研报实体在Oracle中的唯一ID二、Oracle中过滤时间序列数据三、CYPHER ... [详细]
  • 本文详细介绍了Go语言中的数组,包括其基本概念、声明方式、初始化方法以及常见操作。 ... [详细]
  • 在尝试将 mysqldump 文件加载到新的 MySQL 服务器时,遇到因使用保留关键字 'table' 导致的语法错误。 ... [详细]
  • 传统上,Java 的 String 类一直使用 char 数组来存储字符数据。然而,在 Java 9 及更高版本中,String 类的内部实现改为使用 byte 数组。本文将探讨这一变化的原因及其带来的好处。 ... [详细]
  • 一个建表一个执行crud操作建表代码importandroid.content.Context;importandroid.database.sqlite.SQLiteDat ... [详细]
  • MySQL初级篇——字符串、日期时间、流程控制函数的相关应用
    文章目录:1.字符串函数2.日期时间函数2.1获取日期时间2.2日期与时间戳的转换2.3获取年月日、时分秒、星期数、天数等函数2.4时间和秒钟的转换2. ... [详细]
  • HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送www方式的数据。HTTP协议采用了请求响应模型。客服端向服务器发送一 ... [详细]
  • 本文介绍了UUID(通用唯一标识符)的概念及其在JavaScript中生成Java兼容UUID的代码实现与优化技巧。UUID是一个128位的唯一标识符,广泛应用于分布式系统中以确保唯一性。文章详细探讨了如何利用JavaScript生成符合Java标准的UUID,并提供了多种优化方法,以提高生成效率和兼容性。 ... [详细]
author-avatar
郑郑郑克_583
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有