Oracle分区表的哈希分区表的使用和扩展

哈希分区是通过使用分区密钥上的哈希算法来确定数据的分区。使用哈希分区有什么好处

常见的分区表的优点:如提高数据的可用性,降低管理人员的负担,提高报表的性能,和哈希分区也可以。此外,哈希分区表是基于分区键的哈希计算结果确定,以及特定的分区键的哈希值是固定的。也就是说,哈希分区表的数据是根据分区键值聚合的,而相同的分区键位于同一分区中。
例如,在证券行业,我们经常问一个股票的K线。
假设表的结构如下:

复制代码代码如下所示:
创建表的权益

身份证号码,
trade_date日期,
......);


股票表可能很大,对股票表的查询通常是指定ID,查询一个交易日期或其他信息一段时间。在这种情况下,我们需要如何选择资产表的分区
从单独的表结构,似乎trade_date柱非常适合作为范围划分。但如果我们分区,在前面的需求查询:指定一个ID,查询交易信息在一定范围内,如K线在1年内,该查询往往需要跨分区。我们知道跨分区查询分区表不是很好多次,特别是如果该查询可能跨越很多分区。
你也可以说,我们不是要建立索引的ID,trade_date柱,想想,是不是此时的权益表的数据是由trade_date价值聚集在一个数据块,使用相同的数据trade_date价值,描述了在需求查询前甚至通过索引访问,最终抄表经常读取数据块离散,即每个记录对应一个需要读取表数据块。
如果分区表是在哈希表中构建的,根据散列数据分区键聚合,更适合查询中描述的需求,因为相同的ID记录必须在同一分区中,同时,相同的id值记录落在同一数据块中的概率会在一定程度上增加,由IO减少。
在哈希分区减少IO进行报价,因为只有依靠哈希分区表实现IO操作大规模降价是不现实的,尤其是当股票表记录股票的数量是非常大的,在物理学中记录的不同交易日股票同样也收集相同的数据块很难。事实上,如果我们使用物联网表组织模式对资产表的哈希分区的基础上,上述的查询性能可以大大提高。物联网表不在本文的讨论范围之内,并没有进一步的讨论。
在决定使用哈希表之前,我们需要确保所选分区键值是连续的或接近连续的分区。此外,分区的数量需要2的整数次幂,如2,4, 8.these要求是通过散列函数的特点所决定的,所以,我们分区的分区中包含的数据量将更为平均。

哈希分区表的扩展:

哈希分区表被添加分区命令添加到分区。Oracle建议分区的数量是2的幂,例如,检查..这样,确保数据均匀分布在各个分区中,当然,正如前面提到的,分区键值也必须连续分布或接近于连续分布。
添加新分区时,需要将旧分区的旧数据划分为新分区。在选择源划分时应遵循哪些原则
要点如下:如果增加分区的分区的整数N,功率最小的2大于或等于N M当增加N分区,这个分区的数据来自分区N-M / 2。
例如,现在有一个哈希分区表有100个分区,我们要为它添加一个分区,然后是101个分区,即N以上公式是101,超过101的最低2的128的整数次幂,m是128,那么101个分区的数据源它应该是101-128 / 2 = 37分。
从另一个角度来看,当我们增加第一百零一个分区时,我们需要锁定37个分区,因为我们需要将分区中的一部分数据插入到新的101分区中。
接下来,我们用一个例子来验证上面的语句,看看实际操作中需要注意什么:
商品表是我们系统中的一个大表。几年前,当为表创建哈希分区表时,DBA在选择分区号时指定了100个分区。

复制代码代码如下所示:
选择table_name,partition_position,partition_name,从user_tab_partitions哪里table_name = 'commodity 是由partition_position num_rows;
table_name partition_position partition_name num_rows
----------------------------------------------------------------
商品1 cot_ind01_p1 4405650
商品2 cot_ind01_p2 5046650
商品3 cot_ind01_p3 5107550
......
商品36 cot_ind01_p36 5718800
商品37 cot_ind01_p37 9905200
商品38 cot_ind01_p38 10118400
商品39 cot_ind01_p39 10404950
商品40 cot_ind01_p40 9730850
商品41 cot_ind01_p41 9457300
商品42 cot_ind01_p42 9717950
商品43 cot_ind01_p43 9643900
商品44 cot_ind01_p44 11138000
商品45 cot_ind01_p45 9381300
商品46 cot_ind01_p46 10101150
商品47 cot_ind01_p47 8809950
商品48 cot_ind01_p48 10611050
商品49 cot_ind01_p49 10010600
商品50 cot_ind01_p50 8252600
商品51 cot_ind01_p51 9709900
商品52 cot_ind01_p52 8983200
商品53 cot_ind01_p53 9012750
商品54 cot_ind01_p54 9310650
商品55 cot_ind01_p55 8966450
商品56 cot_ind01_p56 8832650
商品57 cot_ind01_p57 9470600
商品58 cot_ind01_p58 8932450
商品59 cot_ind01_p59 9994850
商品60 cot_ind01_p60 9617450
商品61 cot_ind01_p61 10278850
商品62 cot_ind01_p62 9277600
商品63 cot_ind01_p63 8136300
商品64 cot_ind01_p64 10064600
商品65 cot_ind01_p65 3710900
......
商品99 cot_ind01_p99 5273800
商品100 cot_ind01_p100 5293350
选择100行。


通过查询每个分区的数据分布,我们可以看到一些记录从37到64的28个分区的分区是大约两倍的其他分区,因为100不是2的整数次幂,Oracle的hash函数不能保证数据的平均分布。我们添加一个新分区cot_ind01_p101:此表

复制代码代码如下所示:
修改表nts_commodity_ts添加分区cot_ind01_p101;
表的改变。
经过:00:06: 58.52


收集统计信息后,查询新分区记录的数量:

复制代码代码如下所示:
选择table_name,partition_position,partition_name,从user_tab_partitions哪里table_name = 'commodity partition_name num_rows,partition_name,

table_name partition_position partition_name num_rows
-------------------------------------------------------------------
商品37 cot__ind01_p37 4905200
商品101 cot_ind01_p101 5107550


在这一点上,我们可以看到分区37中的数据接近分区37和101的分区。
监视分区进程中的会话锁,我们发现在发现期间两个对象被锁定在独占模式中:

复制代码代码如下所示:
SQL >选择*从V $锁在SID = 1239型= 'tm lmode = 6阶的。
地址kaddr SID TY Id1 ID2 lmode请求CTime块
--------------------------------------------------------------------------------------------------------
ffffffff 7d764828 ffffffff 7d764888 1239 TM 4004126060722
ffffffff 7d764828 ffffffff 7d764888 1239 TM 4004063060722
它们的对象分别是什么
选择object_name,subobject_name,object_id从user_objects object_id在哪里(40041264004063)
object_name subobject_name object_id
-------------------------------------------------------------
商品cot_ind01_p100 4004126
商品cot_ind01_p37 4004063


正如您所看到的,分区37和100是锁定的,因为数据从表中传输,所以需要锁定37个分区。为什么要锁定第一百个分区,也就是最后一个分区
我的理解是:一个新的分区101的位置由原来的分区表100确定的数量决定的,如果在增加原表的分区允许最后一个分区100 DDL操作过程,如合并操作,新增加的101个分区是不是从原来的分区37分布的101个数据,分区本身应该是新的第一百区,造成混乱。在这里,你可能会说,这样的理解,那其他的分区应锁定,太实际上,没有,因为哈希分区表不支持下拉分区操作,只支持合并操作来实现类似的操作,但合并只能从最后一个分区开始。
在哈希表划分过程中增加锁信息的实际指导意义是什么
讨论在上面的例子中,因为最后一个分区的分区37和100将独占锁,因此在这两个分区中添加分区不是DML DML操作,因为需要申请一个共享锁在分区(模式3),这两个分区的应用程序将影响。
添加分区哈希表将不会以及其他类型的分区表完成,如范围分区,因为添加分区是IO操作的过程中,我们需要将数据传输到新的分区。事实上,这并不是最重要的原因,因为哈希表确定划分的根据分区键的哈希函数值,并添加分区的主要时间实际上是在计算哈希值的开支。在上述试验中,添加新的分区操作消耗时间是6分58秒。从以下10046个统计信息中,我们可以看出CPU操作花费了6分钟,这主要是由哈希操作引起的。

{代码}
所有递归语句的总计
调用计数CPU经过的磁盘查询当前行
-----------------------------------------------------------------------
解析3280.17 0.27001480
执行1520360.14 396.30456820 1141620226357 11565252 11565252
取17675.42 21.1821421265400 2862
-----------------------------------------------------------------------
总数3615365.73 417.76478241 1144274226505 11568114 11568114


在测试的情况下,分区cot_ind01_p37有近1000万的数据,这需要近7分钟。假设分区的数据达到1亿,这将需要1个小时以上。如果数量的哈希分区我们建议由Oracle为2的整数次幂,然后我们增加原来的分区一分区中的增加新的分区,如原来的分区是128,需要增加128扩展分区时乘以每增加哈希表的分区所需的时间是一个非常可怕的分区操作。
In a word, the Hash partition has its advantages, but there are also serious defects, such as the partition extension problem described here.Therefore, at the beginning of the project design, we need to choose the number of partitions carefully.But with the increase of data volume, it is very difficult for us to avoid partitioning operations to partition tables. 此操作是一个耗费资源的操作。在操作过程中,锁的问题会影响原始分区的操作,但是如果我们不扩展分区,因为我们害怕前面的问题,数据量越多,增加分区操作的难度就越大。