当前位置:首页 » 操作系统 » 哈希算法分区

哈希算法分区

发布时间: 2022-07-25 16:23:14

❶ PHP mysql 实现hash分区的问题

当分片索引不是纯整型的字符串时,只接受整型的内置 hash 算法是无法使用的。为此,stringhash 按照用户定义的起点和终点去截取分片索引字段中的部分字符,根据当中每个字符的二进制 unicode 值换算出一个长整型数值,然后就直接调用内置 hash 算法求解分片路由:先求模得到逻辑分片号,再根据逻辑分片号直接映射到物理分片。

  • 用户需要在 rule.xml 中定义 partitionLength[] 和 partitionCount[] 两个数组和 hashSlice 二元组。

  • 在 DBLE 的启动阶段,点乘两个数组得到模数,也是逻辑分片的数量

  • 并且根据两个数组的叉乘,得到各个逻辑分片到物理分片的映射表(物理分片数量由 partitionCount[] 数组的元素值之和)

  • 此外根据 hashSlice 二元组,约定把分片索引值中的第 4 字符到第 5 字符(字符串以 0 开始编号,编号 3 到编号 4 等于第 4 字符到第 5 字符)字符串用于 “字符串->整型”的转换

  • 在 DBLE 的运行过程中,用户访问使用这个算法的表时,WHERE 子句中的分片索引值会被提取出来,取当中的第 4 个字符到第 5 字符,送入下一步

  • 设置一个初始值为 0 的累计值,逐个取字符,把累计值乘以 31,再把这个字符的 unicode 值当成长整型加入到累计值中,如此类推直至处理完截取出来的所有字符,此时的累计值就能够代表用户的分片索引值,完成了 “字符串->整型” 的转换

  • 对上一步的累计值进行求模,得到逻辑分片号

  • 再根据逻辑分片号,查映射表,直接得到物理分片号

  • 与MyCat的类似分片算法对比

    两种算法在string转化为int之后,和 hash 分区算法相同,区别也继承了 hash 算法的区别。

    开发注意点

    【分片索引】1. 必须是字符串

    【分片索引】2. 最大物理分片配置方法是,让 partitionCount[] 数组和等于 2880

    例如:

  • <property name="partitionLength">1</property><property name="partitionCount">2880</property>

  • <property name="partitionLength">1,1</property><property name="partitionCount">1440,1440</property>

  • 【分片索引】3. 最小物理分片配置方法是,让 partitionCount[] 数组和等于 1

    例如

  • <property name="partitionLength">2880</property><property name="partitionCount">1</property>

  • 【分片索引】4. partitionLength 和 partitionCount 被当做两个逗号分隔的一维数组,它们之间的点乘必须在 [1, 2880] 范围内

    【分片索引】5. partitionLength 和 partitionCount 的配置对顺序敏感

  • <property name="partitionLength">512,256</property><property name="partitionCount">1,2</property>

  • <property name="partitionLength">256,512</property><property name="partitionCount">2,1</property>

  • 是不同的分片结果

    【分片索引】6. 分片索引字段长度小于用户指定的截取长度时,截取长度会安全减少到符合分片索引字段长度

    【数据分布】1. 分片索引字段截取越长则越有利于数据均匀分布

    【数据分布】2. 分片索引字段的内容重复率越低则越有利于数据均匀分布

    运维注意点

    【扩容】1. 预先过量分片,并且不改变 partitionCount 和 partitionLength 点乘结果,也不改变截取设置 hashSlice 时,可以避免数据再平衡,只需进行涉及数据的迁移

    【扩容】2. 若需要改变 partitionCount 和 partitionLength 点乘结果或改变截取设置 hashSlice 时,需要数据再平衡

    【缩容】1. 预先过量分片,并且不改变 partitionCount 和 partitionLength 点乘结果,也不改变截取设置 hashSlice 时,可以避免数据再平衡,只需进行涉及数据的迁移

    【缩容】2. 若需要改变 partitionCount 和 partitionLength 点乘结果或改变截取设置 hashSlice 时,需要数据再平衡

    配置注意点

    【配置项】1. 在 rule.xml 中,可配置项为<property name="partitionLength"> 、<property name="partitionCount"> 和 <property name="hashSlice">

    【配置项】2.在 rule.xml 中配置 <property name="partitionLength">标签

    内容形式为:<物理分片持有的虚拟分片数>[,<物理分片持有的虚拟分片数>,...<物理分片持有的虚拟分片数>]

    物理分片持有的虚拟分片数必须是整型,物理分片持有的虚拟分片数从左到右与同顺序的物理分片数对应,partitionLength 和partitionCount 的点乘结果必须在 [1, 2880] 范围内

    【配置项】3. 在 rule.xml 中配置 <property name="partitionCount">标签
    内容形式为:<物理分片数>[,<物理分片数>,...<物理分片数>]

    其中物理分片数必须是整型,物理分片数按从左到右的顺序与同顺序的物理分片持有的虚拟分片数对应,物理分片的编号从左到右连续递进,partitionLength 和 partitionCount 的点乘结果必须在 [1, 2880] 范围内

    【配置项】4. partitionLength 和 partitionCount 的语义是:持有partitionLength[i] 个虚拟分片的物理分片有 partitionCount[i] 个

    例如

  • <property name="partitionLength">512,256</property><property name="partitionCount">1,2</property>

  • 语义是持有 512 个逻辑分片的物理分片有 1 个,紧随其后,持有 256 个逻辑分片的物理分片有 2 个

    【配置项】5.partitionLength 和 partitionCount 都对书写顺序敏感,

    例如

  • <property name="partitionLength">512,256</property><property name="partitionCount">1,2</property>

  • 分片结果是第一个物理分片持有头512个逻辑分片,第二个物理分片持有紧接着的256个逻辑分片,第三个物理分片持有最后256个逻辑分片,相对的

  • <property name="partitionLength">256,512</property><property name="partitionCount">2,1</property>

  • 分片结果则是第一个物理分片持有头 256 个逻辑分片,第二个物理分片持有紧接着的 256 个逻辑分片,第三个物理分片持有最后 512 个逻辑分片

    【配置项】6.partitionLength[] 的元素全部为 1 时,这时候partitionCount 数组和等于 partitionLength 和 partitionCount 的点乘,物理分片和逻辑分片就会一一对应,该分片算法等效于直接取余

    【配置项】7.在 rule.xml 中配置标签,从分片索引字段的第几个字符开始截取到第几个字符:

  • 若希望从首字符开始截取 k 个字符( k 为正整数),配置的内容形式可以为“ 0 : k ”、“ k ”或“ : k ”;

  • 若希望从末字符开始截取 k 个字符( k 为正整数),则配置的内容形式可以为“ -k : 0 ”、“ -k ”或“ -k : ”;

  • 若希望从头第 m 个字符起算截取 n 个字符( m 和 n 都是正整数),则先计算出 i = m - 1 和 j = i + n - 1,配置的内容形式为“ i : j ”;

  • 若希望从尾第 m 个字符起算截取从尾算起的 n 个字符( m 和 n 都是正整数),则先计算出 i = -m + n - 1,配置的内容形式可以为“ -m : i ”;

  • 若希望不截取,则配置的内容形式可以为“ 0 : 0 ”、“ 0 : ”、“ : 0 ”或 “ : ”

❷ hash算法原理

Hash Join概述 Hash join算法的一个基本思想就是根据小的row sources(称作build input,我们记较小的表为S,较大的表为B) 建立一个可以存在于hash area内存中的hash table,然后用大的row sources(称作probe input) 来探测前面所建的hash table。如果hash area内存不够大,hash table就无法完全存放在hash area内存中。针对这种情况,Oracle在连接键利用一个hash函数将build input和probe input分割成多个不相连的分区(分别记作Si和Bi),这个阶段叫做分区阶段;然后各自相应的分区,即Si和Bi再做Hash join,这个阶段叫做join阶段。如果在分区后,针对某个分区所建的hash table还是太大的话,oracle就采用nested-loops hash join。所谓的nested-loops hash join就是对部分Si建立hash table,然后读取所有的Bi与所建的hash table做连接,然后再对剩余的Si建立hash table,再将所有的Bi与所建的hash table做连接,直至所有的Si都连接完了。 Hash Join算法有一个限制,就是它是在假设两张表在连接键上是均匀的,也就是说每个分区拥有差不多的数据。但是实际当中数据都是不均匀的,为了很好地解决这个问题,oracle引进了几种技术,位图向量过滤、角色互换、柱状图,这些术语的具体意义会在后面详细介绍。 二. Hash Join原理我们用一个例子来解释Hash Join算法的原理,以及上述所提到的术语。考虑以下两个数据集。 S={1,1,1,3,3,4,4,4,4,5,8,8,8,8,10} B={0,0,1,1,1,1,2,2,2,2,2,2,3,8,9,9,9,10,10,11} Hash Join的第一步就是判定小表(即build input)是否能完全存放在hash area内存中。如果能完全存放在内存中,则在内存中建立hash table,这是最简单的hash join。如果不能全部存放在内存中,则build input必须分区。分区的个数叫做fan-out。Fan-out是由hash_area_size和cluster size来决定的。其中cluster size等于db_block_size * hash_multiblock_io_count,hash_multiblock_io_count在oracle9i中是隐含参数。这里需要注意的是fan-out并不是build input的大小/hash_ara_size,也就是说oracle决定的分区大小有可能还是不能完全存放在hash area内存中。大的fan-out导致许多小的分区,影响性能,而小的fan-out导致少数的大的分区,以至于每个分区不能全部存放在内存中,这也影响hash join的性能。 Oracle采用内部一个hash函数作用于连接键上,将S和B分割成多个分区,在这里我们假设这个hash函数为求余函数,即Mod(join_column_value,10)。这样产生十个分区,如下表. 经过这样的分区之后,只需要相应的分区之间做join即可(也就是所谓的partition pairs),如果有一个分区为NULL的话,则相应的分区join即可忽略。 在将S表读入内存分区时,oracle即记录连接键的唯一值,构建成所谓的位图向量,它需要占hash area内存的5%左右。在这里即为{1,3,4,5,8,10}。 当对B表进行分区时,将每一个连接键上的值与位图向量相比较,如果不在其中,则将其记录丢弃。在我们这个例子中,B表中以下数据将被丢弃 {0,0,2,2,2,2,2,2,9,9,9,9,9}。这个过程就是位图向量过滤。 当S1,B1做完连接后,接着对Si,Bi进行连接,这里oracle将比较两个分区,选取小的那个做build input,就是动态角色互换,这个动态角色互换发生在除第一对分区以外的分区上面。

❸ oracle什么时候选择hash join算法

Hash Join只能用于相等连接,且只能在CBO优化器模式下。相对于nested loop join,hash join更适合处理大型结果集Hash Join的执行计划第1个是hash表(build table),第2个探查表(probe table),一般不叫内外表,nested loop才有内外表Hash表也就是所谓的内表,探查表所谓的外表
两者的执行计划形如:
nested loop
outer table --驱动表
inner table
hash join
build table (inner table) --驱动表
probe table (outer table)
先看一张图片,大致了解Hash Join的过程:
深入理解Oracle表:三大表连接方式详解之Hash Join的定义,原理,算法,成本,模式和位图 - Andy - Andys home下面详细了解一下Hash Join
一 Hash join概念
Hash join算法的一个基本思想就是根据小的row sources(称作build input 也就是前文提到的build table,我们记较小的表为S,较大的表为B)建立一个可以存在于hash area内存中的hash table然后用大的row sources(称作probe input,也就是前文提到的probe table) 来探测前面所建的hash table如果hash area内存不够大,hash table就无法完全存放在hash area内存中针对这种情况,Oracle在连接键利用一个hash函数将build input和probe input分割成多个不相连的分区分别记作Si和Bi,这个阶段叫做分区阶段;然后各自相应的分区,即Si和Bi再做Hash join,这个阶段叫做join阶段如果HASH表太大,无法一次构造在内存中,则分成若干个partition,写入磁盘的temporary segment,则会多一个写的代价,会降低效率至于小表的概念,对于 hash join 来说,能容纳在 pga 中的 hash table 都可以叫小表,通常比如:
pga_aggregate_target big integer 1073741824hash area size 大体能使用到40多 M ,这样的话通常可能容纳 几十万的记录hash area size缺省是2*sort_area_size,我们可以直接修改SORT_AREA_SIZE 的大小,HASH_AREA_SIZE也会跟着改变的如果你的workarea_size_policy=auto,那么我们只需设定pga_aggregate_target但请记住,这是一个session级别的参数,有时,我们更倾向于把hash_area_size的大小设成驱动表的1.6倍左右驱动表仅仅用于nested loop join 和 hash join,但Hash join不需要在驱动表上存在索引,而nested loop join则迫切需求一两百万记录的表 join上 千万记录的表,hash join的通常表现非常好不过,多与少,大与小,很多时候很难量化,具体情况还得具体分析如果在分区后,针对某个分区所建的hash table还是太大的话,oracle就采用nested loop hash join所谓的nested-loops hash join就是对部分Si建立hash table,然后读取所有的Bi与所建的hash table做连接然后再对剩余的Si建立hash table,再将所有的Bi与所建的hash table做连接,直至所有的Si都连接完了二 Hash Join原理
考虑以下两个数据集:
S={1,1,1,3,3,4,4,4,4,5,8,8,8,8,10}
B={0,0,1,1,1,1,2,2,2,2,2,2,3,8,9,9,9,10,10,11}
Hash Join的第一步就是判定小表(即build input)是否能完全存放在hash area内存中如果能完全存放在内存中,则在内存中建立hash table,这是最简单的hash join如果不能全部存放在内存中,则build input必须分区。分区的个数叫做fan-outFan-out是由hash_area_size和cluster size来决定的。其中cluster size等于db_block_size * _hash_multiblock_io_counthash_multiblock_io_count是个隐藏参数,在9.0.1以后就不再使用了[sql]
sys@ORCL> ed
Wrote file afiedt.buf
1 select a.ksppinm name,b.ksppstvl value,a.ksppdesc description2 from x$ksppi a,x$ksppcv b
3 where a.indx = b.indx
4* and a.ksppinm like '%hash_multiblock_io_count%'
sys@ORCL> /
NAME VALUE DESCRIPTION
------------------------------ ----- ------------------------------------------------------------_hash_multiblock_io_count 0 number of blocks hash join will read/write at onceOracle采用内部一个hash函数作用于连接键上,将S和B分割成多个分区在这里我们假设这个hash函数为求余函数,即Mod(join_column_value,10)这样产生十个分区,如下表:
深入理解Oracle表:三大表连接方式详解之Hash Join的定义,原理,算法,成本,模式和位图 - Andy - Andys home经过这样的分区之后,只需要相应的分区之间做join即可(也就是所谓的partition pairs)如果有一个分区为NULL的话,则相应的分区join即可忽略在将S表读入内存分区时,oracle即记录连接键的唯一值,构建成所谓的位图向量它需要占hash area内存的5%左右。在这里即为{1,3,4,5,8,10}
当对B表进行分区时,将每一个连接键上的值与位图向量相比较,如果不在其中,则将其记录丢弃在我们这个例子中,B表中以下数据将被丢弃{0,0,2,2,2,2,2,2,9,9,9,9,9}
这个过程就是位图向量过滤
当S1,B1做完连接后,接着对Si,Bi进行连接
这里oracle将比较两个分区,选取小的那个做build input,就是动态角色互换这个动态角色互换发生在除第一对分区以外的分区上面三 Hash Join算法
第1步:判定小表是否能够全部存放在hash area内存中,如果可以,则做内存hash join。如果不行,转第二步第2步:决定fan-out数
(Number of Partitions) * C<= Favm *M
其中C为Cluster size,其值为DB_BLOCK_SIZE*HASH_MULTIBLOCK_IO_COUNTFavm为hash area内存可以使用的百分比,一般为0.8左右M为Hash_area_size的大小
第3步:读取部分小表S,采用内部hash函数(这里称为hash_fun_1)将连接键值映射至某个分区,同时采用hash_fun_2函数对连接键值产生另外一个hash值这个hash值用于创建hash table用,并且与连接键值存放在一起第4步:对build input建立位图向量
第5步:如果内存中没有空间了,则将分区写至磁盘上第6步:读取小表S的剩余部分,重复第三步,直至小表S全部读完第7步:将分区按大小排序,选取几个分区建立hash table(这里选取分区的原则是使选取的数量最多)第8步:根据前面用hash_fun_2函数计算好的hash值,建立hash table第9步:读取表B,采用位图向量进行位图向量过滤第10步:对通过过滤的数据采用hash_fun_1函数将数据映射到相应的分区中去,并计算hash_fun_2的hash值第11步:如果所落的分区在内存中,则将前面通过hash_fun_2函数计算所得的hash值与内存中已存在的hash table做连接将结果写致磁盘上。如果所落的分区不在内存中,则将相应的值与表S相应的分区放在一起第12步:继续读取表B,重复第9步,直至表B读取完毕第13步:读取相应的(Si,Bi)做hash连接。在这里会发生动态角色互换第14步:如果分区过后,最小的分区也比内存大,则发生nested-loop hash join四 Hash Join的成本
⑴ In-Memory Hash Join
Cost(HJ)=Read(S)+ build hash table in memory(CPU)+Read(B) + Perform In memory Join(CPU)忽略cpu的时间,则:
Cost(HJ)=Read(S)+Read(B)
⑵ On-Disk Hash Join
根据上述的步骤描述,我们可以看出:
Cost(HJ)=Cost(HJ1)+Cost(HJ2)
其中Cost(HJ1)的成本就是扫描S,B表,并将无法放在内存上的部分写回磁盘,对应前面第2步至第12步Cost(HJ2)即为做nested-loop hash join的成本,对应前面的第13步至第14步其中Cost(HJ1)近似等于Read(S)+Read(B)+Write((S-M)+(B-B*M/S))因为在做nested-loop hash join时,对每一chunk的build input,都需要读取整个probe input,因此Cost(HJ2)近似等于Read((S-M)+n*(B-B*M/S)),其中n是nested-loop hash join需要循环的次数:n=(S/F)/M一般情况下,如果n大于10的话,hash join的性能将大大下降从n的计算公式可以看出,n与Fan-out成反比例,提高fan-out,可以降低n当hash_area_size是固定时,可以降低cluster size来提高fan-out从这里我们可以看出,提高hash_multiblock_io_count参数的值并不一定提高hash join的性能五 Hash Join的过程
一次完整的hash join如下:
1 计算小表的分区(bucket)数--Hash分桶
决定hash join的一个重要因素是小表的分区(bucket)数这个数字由hash_area_size、hash_multiblock_io_count和db_block_size参数共同决定Oracle会保留hash area的20%来存储分区的头信息、hash位图信息和hash表因此,这个数字的计算公式是:
Bucket数=0.8*hash_area_size/(hash_multiblock_io_count*db_block_size)2 Hash计算
读取小表数据(简称为R),并对每一条数据根据hash算法进行计算Oracle采用两种hash算法进行计算,计算出能达到最快速度的hash值(第一hash值和第二hash值)而关于这些分区的全部hash值(第一hash值)就成为hash表3 存放数据到hash内存中
将经过hash算法计算的数据,根据各个bucket的hash值(第一hash值)分别放入相应的bucket中第二hash值就存放在各条记录中
4 创建hash位图
与此同时,也创建了一个关于这两个hash值映射关系的hash位图5 超出内存大小部分被移到磁盘
如果hash area被占满,那最大一个分区就会被写到磁盘(临时表空间)上去任何需要写入到磁盘分区上的记录都会导致磁盘分区被更新这样的话,就会严重影响性能,因此一定要尽量避免这种情况2-5一直持续到整个表的数据读取完毕
6 对分区排序
为了能充分利用内存,尽量存储更多的分区,Oracle会按照各个分区的大小将他们在内存中排序7 读取大表数据,进行hash匹配
接下来就开始读取大表(简称S)中的数据
按顺序每读取一条记录,计算它的hash值,并检查是否与内存中的分区的hash值一致如果是,返回join数据
如果内存中的分区没有符合的,就将S中的数据写入到一个新的分区中,这个分区也采用与计算R一样的算法计算出hash值也就是说这些S中的数据产生的新的分区数应该和R的分区集的分区数一样。这些新的分区被存储在磁盘(临时表空间)上8 完全大表全部数据的读取
一直按照7进行,直到大表中的所有数据的读取完毕9 处理没有join的数据
这个时候就产生了一大堆join好的数据和从R和S中计算存储在磁盘上的分区10 二次hash计算
从R和S的分区集中抽取出最小的一个分区,使用第二种hash函数计算出并在内存中创建hash表采用第二种hash函数的原因是为了使数据分布性更好11 二次hash匹配
在从另一个数据源(与hash在内存的那个分区所属数据源不同的)中读取分区数据,与内存中的新hash表进行匹配。返回join数据12 完成全部hash join
继续按照9-11处理剩余分区,直到全部处理完毕六 Hash Join的模式
Oracle中,Hash Join也有三种模式:optimal,one-pass,multi-pass⑴ optimal
当驱动结果集生成的hash表全部可以放入PGA的hash area时,称为optimal,大致过程如下:
① 先根据驱动表,得到驱动结果集
② 在hash area生成hash bulket,并将若干bulket分成一组,成为一个partition,还会生成一个bitmap的列表,每个bulket在上面占一位③ 对结果集的join键做hash运算,将数据分散到相应partition的bulket中当运算完成后,如果键值唯一性较高的话,bulket里的数据会比较均匀,也有可能有的桶里面数据会是空的这样bitmap上对应的标志位就是0,有数据的桶,标志位会是1④ 开始扫描第二张表,对jion键做hash运算,确定应该到某个partition的某个bulket去探测探测之前,会看这个bulket的bitmap是否会1,如果为0,表示没数据,这行就直接丢弃掉⑤ 如果bitmap为1,则在桶内做精确匹配,判断OK后,返回数据这个是最优的hash join,他的成本基本是两张表的full table scan,在加微量的hash运算博客开篇的那幅图描述的也就是这种情况
⑵ one-pass
如果进程的pga很小,或者驱动表结果集很大,超过了hash area的大小,会怎么办?
当然会用到临时表空间,此时oracle的处理方式稍微复杂点需奥注意上面提到的有个partition的概念可以这么理解,数据是经过两次hash运算的,先确定你的partition,再确定你的bulket假设hash area小于整个hash table,但至少大于一个partition的size,这个时候走的就是one-pass当我们生成好hash表后,状况是部分partition留在内存中,其他的partition留在磁盘临时表空间中当然也有可能某个partition一半在内存,一半在磁盘,剩下的步骤大致如下:
① 扫描第二张表,对join键做hash运算,确定好对应的partition和bulket② 查看bitmap,确定bulket是否有数据,没有则直接丢弃③ 如果有数据,并且这个partition是在内存中的,就进入对应的桶去精确匹配,能匹配上,就返回这行数据,否则丢弃④ 如果partition是在磁盘上的,则将这行数据放入磁盘中暂存起来,保存的形式也是partition,bulket的方式⑤ 当第二张表被扫描完后,剩下的是驱动表和探测表生成的一大堆partition,保留在磁盘上⑥ 由于两边的数据都按照相同的hash算法做了partition和bulket,现在只要成对的比较两边partition数据即可并且在比较的时候,oracle也做了优化处理,没有严格的驱动与被驱动关系他会在partition对中选较小的一个作为驱动来进行,直到磁盘上所有的partition对都join完可以发现,相比optimal,他多出的成本是对于无法放入内存的partition,重新读取了一次,所以称为one-pass只要你的内存保证能装下一个partition,oracle都会腾挪空间,每个磁盘partition做到one-pass⑶ multi-pass
这是最复杂,最糟糕的hash join
此时hash area小到连一个partition也容纳不下,当扫描好驱动表后可能只有半个partition留在hash area中,另半个加其他的partition全在磁盘上剩下的步骤和one-pass比价类似,不同的是针对partition的处理由于驱动表只有半个partition在内存中,探测表对应的partition数据做探测时如果匹配不上,这行还不能直接丢弃,需要继续保留到磁盘,和驱动表剩下的半个partition再做join这里举例的是内存可以装下半个partition,如果装的更少的话,反复join的次数将更多当发生multi-pass时,partition物理读的次数会显着增加七 Hash Join的位图
这个位图包含了每个hash分区是否有有值的信息。它记录了有数据的分区的hash值这个位图的最大作用就是,如果probe input中的数据没有与内存中的hash表匹配上先查看这个位图,以决定是否将没有匹配的数据写入磁盘那些不可能匹配到的数据(即位图上对应的分区没有数据)就不再写入磁盘八 小结
① 确认小表是驱动表
② 确认涉及到的表和连接键分析过了
③ 如果在连接键上数据不均匀的话,建议做柱状图④ 如果可以,调大hash_area_size的大小或pga_aggregate_target的值⑤ Hash Join适合于小表与大表连接、返回大型结果集的连接

❹ 高手,11g hash分区后的默认排序,是怎么排的

文档内容目标解决方案快速重建统计信息的推荐步骤关于收集optimizer统计信息的重要文档收集对象的统计信息使用足够大的samplesize收集所有对象的统计信息收集字段的统计信息/数据非均匀分布列的histogram收集分区对象的GlobalStatistics(全局统计信息)收集SystemStatistics(系统统计信息)从早期版本升级到11g缺省设置统计信息收集命令的例子在单一的表收集统计信息收集某一schema下的所有对象的统计信息收集database中所有对象的统计信息:参考适用于:OracleDatabase-EnterpriseEdition-版本11.1.0.6到11.2.0.3[发行版11.1到11.2]OracleDatabase-StandardEdition-版本11.1.0.6到11.2.0.3[发行版11.1到11.2]OracleDatabase-PersonalEdition-版本11.1.0.6到11.2.0.3[发行版11.1到11.2]本文档所含信息适用于所有平台目标这篇文档概述了在Oracle11g中收集CBO(CostBasedOptimizer)的统计信息的推荐方法。对于其它版本请参见:Document1226841.1HowTo:注:下面这个文档中有个标题为""的章节,该章节提供了关于收集统计信息的一些其它建议Document:1380043.解决方案快速重建统计信息的推荐步骤为快速删除和重建某张表及它的索引的统计信息(包含非均匀分布列的统计信息),推荐如下:execdbms_stats.delete_table_stats(ownname=>'user_name',-tabname=>'table_name',cascade_indexes=>true);execdbms_stats.gather_table_stats(ownname=>'user_name',-tabname=>'table_name',-estimate_percent=>DBMS_STATS.AUTO_SAMPLE_SIZE,-cascade=>true,-method_opt=>'forallcolumnssizeAUTO');随后我们会解释这样推荐的原因。同样,后边会有收集统计信息的例子。需要注意的是,从10gR2开始,下边的方法可以用来恢复统计信息:Document452011.1*关于收集optimizer统计信息的重要文档这些推荐适用于大多数的数据库。这些推荐的目的是为了尽可能生成准确的统计信息,为此我们推荐使用的samplesize(采样率)为100%。这是因为samplesize的减少可能会导致生成的统计信息不准确。一般来说使用100%的samplesize会使收集信息的时间增长,所以需要考虑调整当前使用的maintenancewindow,使统计信息的收集能在一个maintenancewindow完成。如果可能,我们推荐使用预设好的偏好设置使收集不同对象的过程标准化。不同于对不同的对象使用不同的设置,在Database/Schema/Table一级设置默认偏好能使设置集中化,且不需要对不同对象单独设置。自动统计信息收集操作也会使用设置好的默认偏好。关于如何设置默认偏好请详见:Document1493227.尽管默认值对大多数系统都适用,如果您发现某些特定设置比默认值更适合您的系统,那么请自行添加至默认设置中。收集新的optimizer统计信息一般会保持或改进已存在的执行计划,但是也可能使某些查询的性能下降。所以从10gR1开始系统默认会保留最近30天的统计信息,这期间如果遇到问题可以用如下方法恢复到之前的统计信息:Document452011.1*收集新的optimizer的统计信息可能使sharedpool中的cursor无效,所以在数据库负载低的时候执行统计信息收集将是明智的选择,比如maintenancewindow。除了objectstatistics(比如业务表和索引的统计信息),我们推荐对dictionaryobjects(数据字典对象)也收集统计信息:Document457926.'Fixed'Objects?对于非常大的系统,统计信息的收集会是非常消耗时间和资源的工作。在这种情况下需要小心选择samplesize的大小,确保在可接受的时间范围、资源限制和维护窗口内完成收集。请参见以下文档:Document44961.1StatisticsGathering:对于这种系统,我们也推荐使用基于改变的统计信息的收集,避免重复收集不必要的信息。和10g相比,11g的自动统计信息的过程已经发生了改变,详见以下文档:Document237901.-ExamplesDocument756734.111g:(DocID756734.1)Document743507.1WhyHastheGATHER_STATS_JOBbeenremovedin11g?(DocID743507.1)收集对象的统计信息TheCostBasedOptimizer(CBO)是基于统计信息生成特定查询的执行计划的。当samplesize减小的时候,基于抽样出来的样本可能会生成不同的统计信息,这是因为这些样本有可能正好是用某些特定的方法录入的。在11g中,收集统计信息推荐使用定期统计信息收集脚本。在绝大多数情况下系统默认脚本提供的采样率都是合适的,并兼顾了以下推荐:使用足够大的samplesize在11g中,对于ESTIMATE_PERCENT,我们建议使用缺省的DBMS_STATS.AUTO_SAMPLE_SIZE。Oracle首先会判断如果对一个表使用100%的samplesize是否能在一个maintenancewindow中收集完。如果能收集完那么就对这个表使用100%的samplesize,尽管这意味着对这张表收集统计信息的频率会降低。如果100%的samplesize并不可行,那么会至少使用30%作为samplesize。11g使用了一种hash算法来计算统计信息,所以在大多数时候收集信息的性能都是可以接受的。通常,对大部分应用程序而言,相对于数据每天发生的一点点变化,统计信息整体上的准确度更重要一些。这个参数在早期版本的设置请参见之后的文档。收集所有对象的统计信息确保所有对象(表和索引)都收集了统计信息。这个通过使用CASCADE参数可以很容易的实现。收集字段的统计信息/数据非均匀分布列的histogram确保所有数据非均匀分布的列都收集了histogram,并且使用METHOD_OPT参数来确保histogram的精度。通常我们推荐使用缺省的设置“AUTO”。这意味着如果histogram的存在会有助于生成更准确的执行计划,DBMS_STATS会自动在需要字段上生成它。相对于在所有的列上收集histogram,只在确实需要的列上收集是更稳妥的做法。Document390249.1HowToQuicklyAdd/RemoveColumnStatistics(Histograms)ForAColumn注意:假如某个列上的数据是非均匀分布的,并且samplesize不是100%(例如使用AUTO),那么这个列上的某些数据可能会被统计信息给漏掉。假如发生了这种情况,并且查询恰好使用了那些没有histogrambucket对应的值,那么这条查询就不可能使用真正准确的统计信息,进而可能产生不准确甚至是错误的执行计划。在这种情况下,使用100%的samplesize是唯一能保证统计信息准确性的法。假如这是不可行的,移除列上的histogram(只使用列的最大最小值)将使生成的执行计划更加一致,因为selectivity是不变的。同样的道理,假如统计信息不是最新的,histogram的存在甚至会引入额外的问题,比如当查询引用的值是在histogram的范围之外,或者是”frequence”histogram的中间值(比如,列上添加了一个之前不存在的值或者某个特定值的行数发生了很大的变化)。在这样的情况下,optimizer将不得不做一些猜测(有可能是不正确的),从而产生不准确的执行计划。所以,需要通过应用程序测试不同的值以确定哪种统计信息能帮助产生最好的执行计划。需要注意的是由于功能限制目前只有254个buckets可以用来存储列统计信息。如果您的distinctvalue的个数非常大而且上面数据的分布是不均匀的,列的统计信息仍然可能是不准确的。详见:Document212809.还有就是只有当你的应用确实能用到histogram的时候收集它才是有意义的。特别是当你使用绑定变量但不会做窥测(bindpeek)的时候(例如_OPTIM_PEEK_USER_BINDS=FALSE),optimizer不会有任何用来检索histogram的数据,从而也不会因为histogram的存在而更好地估算cardinality。在早期的版本中,参数METHOD_OPT的缺省的设定是"FORALLCOLUMNSSIZE1"。这意味着我们只会收集列的最大最小值,而没有值的具体分布的信息。我们知道,有些时候histogram的存在反而不利于好的执行计划的产生,所以当从一个版本升级到另外一个版本后,用户可能希望先将这个参数设置为之前版本的值,运行一段时间后再调整为当前版本的值,使升级后的初始阶段更加平稳,详见以下文档:Document465787.1Howto:收集分区对象的GlobalStatistics(全局统计信息)如果使用了partition(分区)技术,时间允许的话尽可能收集GlobalStatistics。GlobalStatistics是非常重要的,但因为涉及数据量及收集时间长度的影响,很多时候它都被略过了。假如不能采用100%的samplesize,那么我们推荐至少使用1%来做收集。小的采样(例如0.001,0.0001,0.00001等)可以是非常有效的,但同时要知道大量能帮助optimizer生成准确执行计划的数据会被忽略掉的。参数ESTIMATE_PERCENT有一个非常弹性的有效的范围[0.000001->100],对于非常巨大的表您可以使用非常小的值。不同的系统需要经过测试才能得出最适合这个系统的值。详见以下文档:Document236935.1Globalstatistics-AnExplanation11g同时提供了以增量方式收集GlobalStatistics的方法.详见:(11.1)PartNumberB28274-.3.1.收集SystemStatistics(系统统计信息)收集SystemStatistics来真实反映系统CPU负载情况。除了估算正常I/O部分的cost之外,这些信息会帮助CBO更好的估算CPU部分的cost。详见:Document470316.1UsingActualSystemStatistics(.(CPUandIO)forCBOusageDocument153761.从早期版本升级到11g如果您是从Oracle的早期版本升级到11g,您可以参见以下关于统计信息管理的建议:Document465787.1Howto:/div>缺省设置不同版本收集统计信息时使用的缺省设置可能是不一样的,例如:ESTIMATE_PERCENT的缺省值:9i:100%10g:DBMS_STATS.AUTO_SAMPLE_SIZE(使用非常小的估算百分比)11g:DBMS_STATS.AUTO_SAMPLE_SIZE(使用更大的估算百分比-100%)METHOD_OPT:defaults:9i:"FORALLCOLUMNSSIZE1"等同于没有列值的具体分布信息.10gand11g:"FORALLCOLUMNSSIZEAUTO"-这意味着如果histogram的存在会有助于生成更准确的执行计划,DBMS_STATS会自动在需要字段上生成它。在11g中,AUTO_SAMPLE_SIZE的缺省值是100%,从而尽可能使统计信息是准确的。在之前的版本上,由于时间的制约,100%的samplesize有时候是不可能的,由于11g实施了一个新的hash算法避免了传统的排序(在9i和10g典型慢的部分是排序),这显着的减少了了收集的时间并提升了资源使用效率。同样,是否收集列上的统计信息也是自动决定的,总之11g上还有很多其它类似的改进。您可以使用以下文档中提到的方法来修改默认值:Document1493227.统计信息收集命令的例子在单一的表收集统计信息>execdbms_stats.gather_table_stats(-ownname=>'Schema_name',-tabname=>'Table_name',-estimate_percent=>DBMS_STATS.AUTO_SAMPLE_SIZE,-cascade=>TRUE,-method_opt=>'FORALLCOLUMNSSIZEAUTO');注:如果确定histogram不会对产生更好的执行计划有帮助,那么更好的做法是将下边这一行:method_opt=>'FORALLCOLUMNSSIZEAUTO'替换成method_opt=>'FORALLCOLUMNSSIZE1'注:您需要将'Schema_name'和'Table_name'替换成真正需要收集的schema和table的名字。收集某一schema下的所有对象的统计信息execdbms_stats.gather_schema_stats(-ownname=>'Schema_name',-cascade=>TRUE,-method_opt=>'FORALLCOLUMNSSIZEAUTO');注:将'Schema_name'替换成需要收集的schema的名字。收集database中所有对象的统计信息:execdbms_stats.gather_database_stats(-cascade=>TRUE,-method_opt=>'FORALLCOLUMNSSIZEAUTO');ReferencesNOTE:457926.1-'Fixed'Objects?NOTE:465787.1-Howto:NOTE:236935.1-Globalstatistics-AnExplanationNOTE:237901.1--ExamplesNOTE:44961.1-StatisticsGathering:NOTE:470316.1-UsingActualSystemStatistics(CollectedCPUandIOinformation)NOTE:743507.1-R_STATS_JOBin11g?NOTE:756734.1-11g:NOTE:1226841.1-HowTo:NOTE:1380043.1-(OOW)NOTE:149560.1-(CPUandIO)forCBOuseNOTE:452011.1-*RestoringTableStatistics(Oracle10GOnwards)NOTE:390249.1-HowToQuicklyAdd/RemoveColumnStatistics(Histograms)ForAColumn

❺ 如何使用VeraCrypt创建隐藏分区

使用VeraCrypt创建隐藏分区的方法

  • 准备一份VeraCrypt加密盘文件,加密文件的具体制作方法请参见下面的经验引用,其中有详细的说明

  • 如何使用VeraCrypt

  • 进入程序主界面,单击"加密卷"--"创建加密卷"

  • 随后弹出创建向导,选择"创建文件型加密卷",然后单击"下一步"

  • 选择加密盘类型为:"隐藏的VeraCrypt加密卷",单击"下一步"

  • 选择创建模式为:"直接模式",单击"下一步"

  • 加密盘位置设定:单击"选择文件",弹出选择框,选定你创建好的VeraCrypt加密盘文件,单击"保存",回到加密卷位置对话框,单击"下一步"

  • 输入原有加密盘密码,然后单击"下一步",之后VeraCrypt会校验你的原有加密盘密码并加载加密盘以准备接下来的操作

  • 接下来进入创建加密盘隐藏分区的操作,单击"下一步"

  • 选择加密算法和哈希算法:保持默认即可,单击"下一步"

  • 设定隐藏分区大小:依据你创建好的VeraCrypt加密盘文件来操作。比如我的加密盘大小为197MB,我就将隐藏分区大小设定为70MB,设定好后单击"下一步"

  • 设定隐藏分区密码:设定一个比较复杂但是容易记忆的密码,如果你记性不好,你至少要做到字母和数字混合,6-10位密码即可,然后单击"下一步"(我的密码很简单,只有数字,所以VeraCrypt弹出了提示)

  • 格式化隐藏分区:鼠标在图示区域内滑动,直到下方的进度条走满为止,然后单击"格式化",之后隐藏分区就创建完成了

  • 打开隐藏分区:回到VeraCrypt的主界面,选定一个未被占用的盘符(一般选A:),单击"选择文件",选定刚刚制作好的加密盘文件,单击"保存",程序回到主界面,再单击下面的"加载"

  • 程序要求输入密码,记住,要输入你的隐藏分区密码,之后单击"确定"

  • 隐藏分区就加载完成了,双击A:盘符选项,隐藏分区就弹出来了,就可以往里存文件了

热点内容
java方法定义 发布:2025-01-19 20:20:50 浏览:404
kr脚本 发布:2025-01-19 20:17:41 浏览:518
帮我开启存储 发布:2025-01-19 20:17:39 浏览:813
s9存储缩水 发布:2025-01-19 20:08:06 浏览:335
2b2t的服务器编号是什么 发布:2025-01-19 19:58:55 浏览:874
androidstudio下载与安装 发布:2025-01-19 19:58:14 浏览:560
拉钩算法 发布:2025-01-19 19:58:14 浏览:866
python中读取文件 发布:2025-01-19 19:37:26 浏览:369
网吧电脑连接到steam服务器错误 发布:2025-01-19 19:37:17 浏览:602
mc怎么在别人的服务器开创造 发布:2025-01-19 19:37:16 浏览:71