KingbaseES 全局索引


概述:在分區表上創建的索引可分為全局索引和本地索引。全局索引包括全局非分區索引(Global Nonpartitioned Indexes)和全局分區索引(Global Partitioned Indexes)。

  • 全局分區索引(Global Partitioned Indexes)是指與分區表有不同分區方式的索引,它是在分區表的所有分區數據基礎上創建的分區索引,目前KingbaseES 暫不支持。
  • 本地索引(本地分區索引,Local Partitioned Indexes),是指在每個表分區上單獨創建的索引,是一種局部索引,也是一種分區索引,某一個索引分區只能索引到一個表分區。
  • 需要啟用 enable_globalindexscan = on; 才能使用全局索引。目前只支持select 操作使用全局索引。

1、全局索引例子

create table t1_part(id1 integer,id2 integer,id3 integer)
partition by range(id1)
(
  partition part01 values less than(10000),
  partition part02 values less than(20000),
  partition part03 values less than(30000),
  partition part04 values less than(40000),
  partition part05 values less than(50000),
  partition part06 values less than(60000),
  partition part07 values less than(70000),
  partition part08 values less than(80000),
  partition part09 values less than(90000),
  partition part10 values less than(maxvalue)
);

create unique index idx1_t1_part on t1_part(id1) global ;
create unique index idx2_t1_part on t1_part(id2) global ;
create index idx3_t1_part on t1_part(id2) global ;

注意:並不是global 就一定是全局索引。當創建全局索引時,首先嘗試創建本地索引。當不滿足本地索引的條件(唯一索引的索引列不包括全部分區列或者分區條件為表達式)時會創建全局索引。同樣,啟用分區表上的主鍵/唯一約束時,先嘗試創建本地索引,不滿足時則創建全局唯一索引。可以看到,只有第二個索引才是全局索引。

test=# \di+ idx1_t1_part
                                  List of relations
 Schema |     Name     |       Type        | Owner  |  Table  |  Size   | Description 
--------+--------------+-------------------+--------+---------+---------+-------------
 public | idx1_t1_part | partitioned index | system | t1_part | 0 bytes | 
(1 row)

test=# \di+ idx2_t1_part
                                 List of relations
 Schema |     Name     |     Type     | Owner  |  Table  |    Size    | Description 
--------+--------------+--------------+--------+---------+------------+-------------
 public | idx2_t1_part | global index | system | t1_part | 8192 bytes | 
(1 row)

test=# \di+ idx3_t1_part
                                  List of relations
 Schema |     Name     |       Type        | Owner  |  Table  |  Size   | Description 
--------+--------------+-------------------+--------+---------+---------+-------------
 public | idx3_t1_part | partitioned index | system | t1_part | 0 bytes | 
(1 row)

全局索引支持條件索引,不支持全局分區索引。全局索引不支持排他約束。

 2、全局索引存在的限制

DML操作不允許針對子表 使用全局索引。

test=# delete from t1_part_part04 where id2=31111;   --使用全局索引訪問子表
ERROR:  cannot modify partition t1_part_part04 with global indexes, maintain the partitioned table directly
test=# select * from t1_part_part04 where id2=31111; id1 | id2 | id3 -----+-----+----- (0 rows) test=# delete from t1_part where id2=31111; DELETE 1

3、分區索引與全局索引的性能比較

繼續以上的例子,插入100000 條記錄:

insert into t1_part select generate_series(1,100000),generate_series(1,100000),generate_series(1,100000);

來看執行性能的差異:

test=# declare
test-#   v_result integer;
test-# begin
test-#   for i in 1..100000 loop
test-#      select id3 into v_result from t1_part where id1=i;
test-#   end loop;
test-# end;
test-# /
ANONYMOUS BLOCK
Time: 1320.094 ms (00:01.320)
test=# 
test=# declare
test-#   v_result integer;
test-# begin
test-#   for i in 1..100000 loop
test-#      select id3 into v_result from t1_part where id2=i;
test-#   end loop;
test-# end;
test-# /
ANONYMOUS BLOCK
Time: 4281.198 ms (00:04.281)

比較結果分析:

1、local 索引的訪問效率是 global 索引3倍左右

2、Oracle 的rowid 直接定位數據文件的數據塊,而KingbaseES 的ctid 只是對象文件的第幾塊,因此,KingbaseES 的全局索引需要先定位該 ctid 屬於哪個分區的。

3、KingbaseES 全局索引在索引值包含對象 OID,通過OID找到對應的文件,再通過ctid 訪問。這必然有性能的損耗,但這是因為ctid 的結構所導致的。

4、全局索引暫時不支持index_only_scan

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM