采用多列策略反转键索引

问题描述 投票:0回答:1

我正在分区表上创建本地索引,该表已分区 X(列表分区)

表 TEST 如下所示:

X Z
AB 24 63
AB 24 65
CD 24 63
CD 24 65
EF 24 63

如果我创建索引

在测试(X,Y,Z)本地创建唯一索引TEST_IDX;

我“有效”存储以下内容

AB2463

AB2465

CD2463

CD2465

EF2463

但是,如果我创建反向键索引,那么使用多列时数据如何存储?

在测试(X,Y,Z)上创建唯一索引 TEST_IDX 反转本地;

是否存储为?

3643BA

5643BA

3643DC

5643DC

3643FE

OR 存储为:(我希望是这个)

BA4236

BA4256

DC4236

DC4256

FE4236

实际上,这个表还有更多的列和数百百万行:

X 有 50 个不同的值

Y 有 150 个不同的值

Z 有超过 240000000 个不同的值

我删除并创建了反转键的索引,看起来似乎有所改进,但我担心分区和扩展它

我们每 30 分钟左右就会对此表进行数千次更新,而且更新速度很慢(每次执行 0.20 次)并且他们正在使用该唯一的列

IE:(注意COL A、B、C未在上面显示) 更新测试集 A = :1 、B = :2 、C = :3 其中 X = :4 AND Y = :5 AND Z =:6

oracle indexing reverse database-partitioning
1个回答
0
投票

反向索引反转每个列值的字节顺序。它们不会颠倒索引中列的顺序。所以反向索引将存储:

BA 42 36

BA 42 56

DC 42 36

DC 42 56

FE 42 36

(当然是 Oracle 的编码格式。它不将数字存储为小数,因此 24 的倒数不是 42,但我们只是使用小数来说明这一点)

您可以通过块转储来演示这一点。正常索引转储:

row#0[8014] flag: -------, lock: 2, len=18
col 0; len 2; (2):  41 42  -- encodes A, B
col 1; len 2; (2):  c1 19  -- encodes the number 24
col 2; len 2; (2):  c1 40  -- encodes the number 63
col 3; len 6; (6):  00 75 81 d9 00 00
row#1[7996] flag: -------, lock: 2, len=18
col 0; len 2; (2):  41 42  -- encodes A, B
col 1; len 2; (2):  c1 19
col 2; len 2; (2):  c1 42
col 3; len 6; (6):  00 75 81 d9 00 01
row#2[7978] flag: -------, lock: 2, len=18
col 0; len 2; (2):  43 44  -- encodes C, D
col 1; len 2; (2):  c1 19
col 2; len 2; (2):  c1 40
col 3; len 6; (6):  00 75 81 d9 00 02
row#3[7960] flag: -------, lock: 2, len=18
col 0; len 2; (2):  43 44  -- encodes C, D
col 1; len 2; (2):  c1 19
col 2; len 2; (2):  c1 42
col 3; len 6; (6):  00 75 81 d9 00 03
row#4[7942] flag: -------, lock: 2, len=18
col 0; len 2; (2):  45 46  -- encodes E, F
col 1; len 2; (2):  c1 19
col 2; len 2; (2):  c1 40
col 3; len 6; (6):  00 75 81 d9 00 04

反向索引转储:

row#0[8014] flag: -------, lock: 0, len=18
col 0; len 2; (2):  42 41  -- encodes B, A
col 1; len 2; (2):  19 c1  -- encodes the number 24 *backwards*
col 2; len 2; (2):  40 c1  -- encodes the number 63 *backwards*
col 3; len 6; (6):  00 75 81 d9 00 00
row#1[7996] flag: -------, lock: 0, len=18
col 0; len 2; (2):  42 41  -- encodes B, A
col 1; len 2; (2):  19 c1
col 2; len 2; (2):  42 c1
col 3; len 6; (6):  00 75 81 d9 00 01
row#2[7978] flag: -------, lock: 0, len=18
col 0; len 2; (2):  44 43  -- encodes D, C
col 1; len 2; (2):  19 c1
col 2; len 2; (2):  40 c1
col 3; len 6; (6):  00 75 81 d9 00 02
row#3[7960] flag: -------, lock: 0, len=18
col 0; len 2; (2):  44 43  -- encodes D, C
col 1; len 2; (2):  19 c1
col 2; len 2; (2):  42 c1
col 3; len 6; (6):  00 75 81 d9 00 03
row#4[7942] flag: -------, lock: 0, len=18
col 0; len 2; (2):  46 45  -- encodes F, E
col 1; len 2; (2):  19 c1
col 2; len 2; (2):  40 c1
col 3; len 6; (6):  00 75 81 d9 00 04

请注意,字符串和数字的字节顺序都已颠倒。然而 Oracle 会存储数据类型,它只是反转字节顺序。唯一的例外是 ROWID 本身(转储中的第 3 列)显然没有反转。列相对于彼此的顺序没有改变。

反向索引的目的是将插入分散到叶节点上,这样当您按顺序插入每个增加的列值时,就不会出现热右前缘。如果您遇到争用,这可以帮助减少争用。反转列顺序没有任何好处(如果您愿意,您可以随时自行重新排序列)。反向索引的缺点是,因为字节以相反的顺序存储,所以它们只能用于相等谓词,不能用于不等式,如

>
<
BETWEEN
LIKE
(它可以做 full) 扫描,但不对起始值进行范围扫描/二分查找)。这使得它适用于没有顺序意义的标识符(例如客户 ID),但不适用于日期、反映数量的数字、可能模式匹配的字符串等。通过对表进行哈希分区可以实现相同的好处。唯一的列并使索引成为本地的。这也将把插入分散到许多索引块中,同时仍然保留进行不等式搜索的能力。然而,除非热块争用实际上是一个问题,否则不应使用这两种方法。

© www.soinside.com 2019 - 2024. All rights reserved.