TiDB、OceanBase、PolarDB-X、CockroachDB二級索引寫入效能測評

語言: CN / TW / HK

01  為什麼要做這個測試

二級索引是關係型資料庫相較於NoSQL資料庫的一個關鍵差異。二級索引必須是強一致的,因此索引的寫入需要與主鍵的寫入放在一個事務當中,事務的效能是二級索引效能的基礎。

目前市面上的分散式資料庫中,從使用體驗的角度看主流有幾種形態:

1.以TiDB、CockroachDB等為代表的純透明的用法。 從表現上來看,該種類型的資料庫所有表都是分散式表,並且不需要指定分割槽鍵,其核心邏輯是使用分散式事務來維護全域性索引,並使用全域性索引完全替代單機資料庫中的二級索引。

2.以OceanBase等為代表的純手動的用法。 從表現上看,該種類型的資料庫在不指定分割槽鍵的情況下,是以單表的形式存在的,不具備擴充套件性;建立分散式表需要使用類似分割槽表的語法。此型別的資料庫一般也提供全域性索引的能力(不提供的我們一般稱之為中介軟體而不是資料庫)。但與第一類不同,它們一般會將全域性索引作為一個可選項,由使用者手動的指定與建立。此外,他們還會提供基於單機事務實現的本地索引(本地索引)。

3.同時提供以上兩種用法的PolarDB-X。 在不指定分割槽鍵的情況下,與第一類資料庫類似,使用分散式表+全域性索引來提供透明的分散式體驗;也允許手動指定分割槽鍵,使用本地索引等技術提升效能。

在之前《 PolarDB-X 資料分佈解讀(四) :透明 vs 手動》文章中,我們提出:

1.透明(自動)的易用性決定了分散式資料庫的使用下限,但效能上是有更高的成本代價

2.手動能夠提供最優的效能,但使用門檻會有所增加

分散式資料庫需要為大多數場景提供能夠透明使用的能力,也要為少數效能要求高的場景提供手動調優消除分散式事務的能力。

這個觀點的重要依據是, 純透明的模式本質上是使用分散式事務+全域性索引來替代單機資料庫中的事務+索引,而分散式事務+全域性索引與單機事務+索引存在較大的效能差異。

本次測試將重點關注不同分散式資料庫的索引效能,特別關注業內全域性索引的效能與MySQL索引的效能差異。

本次測試的產品包括 TiDB、 OB、PolarDB-X、CockroachDB ,選取這幾個資料庫有以下原因:

  • 他們都提供了強一致的全域性索引能力,是資料庫而不是中介軟體。

  • 都有開源,並且都有云產品提供,歷史也都比較悠久,資料比較多,不是PPT資料庫,容易搞清楚內部的原理。

  • 都是主要面向OLTP的資料庫。

此外我們也測試了MySQL的索引效能作為對比。

02  測試方法

由於硬體配置(比如 OB 用了6臺機器(並且租戶設定上並沒有佔滿整個機器),TiDB和TiKV用了5臺,PolarDB-X和MySQL是直接公共雲購買的等)、系統引數等等,對於每個資料庫來說,不是完全相同,也不一定是最優的,所以直接對比TPS是沒有意義的。

我們會將每個資料庫,不帶索引情況下,TPS能夠達到的峰值作為基線(100%),比較不同索引數目的效能相對於基線的百分比。

例如,產品A不帶索引能跑到10W的TPS,帶一個索引跑到5W,那我們就認為帶一個索引的情況下是基線的50%。這個百分比我們不妨稱之為TPS百分比。

在產品之間的橫向對比中,我們會對比相同索引數目下的TPS百分比,而不是TPS的絕對值。

在測試TPS百分比的時候,我們會調整併發度,來找到能夠達到最大TPS的併發度,並以最大的TPS來計算TPS百分比。

除了TPS百分比之外,我們還會測試每個產品在不同索引數目情況下,單次寫入的RT。在RT測試中,我們會用單執行緒來進行寫入。

本次測試我們只測試insert場景,這是索引寫入的最基本的功能了。我們使用sysbench的oltp_insert.lua製造流量。由於我們要測試多個索引,因此我們將sysbench的表結構做了修改,以MySQL為例,修改如下:

CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL ,
`k1` int(11) NOT NULL ,
`k2` int(11) NOT NULL ,
`k3` int(11) NOT NULL ,
`k4` int(11) NOT NULL ,
`k5` int(11) NOT NULL ,
`k6` int(11) NOT NULL ,
`k7` int(11) NOT NULL ,
`k8` int(11) NOT NULL ,
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
);

我們在表中增加了8個列,根據測試的索引數目,會在這個8個列上建立相應數目的二級索引。

同時我們要修改oltp_insert.lua,在INSERT語句中增加這8個列,8個列的值隨機生成,沒有有序性,避免在基於range進行分割槽的資料庫(TiDB、CockroachDB)上產生熱點:

  con:query(string.format("INSERT INTO %s (id,k,k1,k2,k3,k4,k5,k6,k7,k8,c,pad) VALUES " ..
"(%d, %d,%d,%d,%d,%d,%d,%d,%d,%d,'%s','%s')",
table_name, i, k_val, sysbench.rand.default(1, sysbench.opt.table_size),sysbench.rand.default(1, sysbench.opt.table_size),sysbench.rand.default(1, sysbench.opt.table_size),sysbench.rand.default(1, sysbench.opt.table_size),sysbench.rand.default(1, sysbench.opt.table_size),sysbench.rand.default(1, sysbench.opt.table_size),sysbench.rand.default(1, sysbench.opt.table_size),sysbench.rand.default(1, sysbench.opt.table_size),c_val, pad_val))

由於不同資料庫的語法、特性等不同,每個資料庫的建表語句可能會做一些修改,每個資料庫最終使用的建表語句放在附錄中。

03  軟硬體環境

本次測試使用的機器使用的是阿里雲上購買的ECS,規格為ecs.i2g.8xlarge:

作業系統為阿里雲上提供的CentOS 8.3:

所有機器均在同一個地域的同一個可用區內。

所有資料庫的資料檔案均放在本地SSD中。

所有資料庫均會在前面掛一個SLB做負載均衡。

sysbench使用的是1.0.20版本。

04  測試結果

我們可以看到, 這些分散式資料庫實現的全域性索引中,即使只有1個索引,效能也都會下跌到30%以下,在8個索引的情況下,效能基本都會跌倒10%以下。

而像 MySQL這種單機資料庫,8個索引的情況下,效能依然保持在85%以上

印證了我們在 PolarDB-X 資料分佈解讀(四) :透明 vs 手動》 提到過的觀點 “分散式事務跟單機事務相比,在成本(或者說效能)上依然存在不可逾越的鴻溝,這個差距至少在3倍以上”。

使用全域性索引替代單機資料庫索引會帶來很高的成本,在成本敏感型的場景中,需要適當的使用本地索引來降低使用成本。

在提供了本地索引的資料庫中:

  • PolarDB-X和OB的本地索引與主鍵具有Locality上的親和性,能使用單機事務來對索引進行寫入,相對於全域性索引,保持了非常高的效能。

  • TiDB雖然提供了本地索引,但其索引和主鍵不具備Locality上的親和性,無法繫結到同一個機器上,因此其本地索引依然要使用分散式事務進行維護,在效能上和全域性索引沒有太大差異,成本都很高。

  • CockroachDB的本地索引理論上與TiDB的行為類似,不過CockroachDB的partition功能是商業版才提供的,這次就沒有進行測試了

對於TiDB和CockroachDB來說,情況就比較尷尬了,因為他們所提供的所有索引,成本都要比單機MySQL高很多。作為使用者沒有任何手段能消除這個代價,除非不用二級索引。

從RT的角度看:

  1. 單機資料庫由於事務的網路互動最少,RT表現的是最好的,並且跟索引的數量幾乎沒有關係。

  2. 分散式資料庫的事務由於需要更多的跨節點互動,所以RT明顯會比單機資料庫更大。但由於分散式資料庫在多分支的事務上一般都會採用並行寫入的策略,因此表現好的資料庫RT並不會隨索引數量的增加而線性增加。總體說來,RT可以接受。

  3. CockroachDB全域性索引的RT表現是最差的,可能跟事務策略使用HLC有關,其他幾個資料庫使用的都是TSO的方案。

  4. TiDB全域性索引的RT表現的是最好的,0-8個索引RT幾乎沒有變化,說明並行優化做的非常好。

  5. 自家產品PolarDB-X全域性索引的RT看起來還有優化的空間,雖然上漲有限,但並沒有做到完全的並行。我們會在後續版本進行優化。本地索引RT非常穩定並且低。

  6. OB的全域性索引和本地索引表現和PolarDB-X比較類似,並行優化有提升空間,本地索引表現不錯。

測試過程中的一個額外發現:

TiDB、OB、CockroachDB的自增主鍵(auto_increment/serial)都有比較嚴重的效能問題,都要使用隨機等替代方案。TiDB與CockroachDB是因為時間序帶來的熱點range導致,OB可能是內部的一些鎖導致。相容性包括功能相容與效能相容,效能相容之路漫漫... ...

下面附上每個資料庫測試的情況。

05  測試詳情

MySQL

環境配置

版本:5.7.14-AliSQL-X-Cluster-1.5.1.8-20201229-log

規格:32C128G,獨享型

阿里雲購買:

測試結果

索引 數量

RT

(單執行緒)

最高TPS

TPS比例

0

0.52

37599

100%

1

0.53

35860

95%

2

0.63

34859

93%

4

0.62

33338

89%

8

0.58

31636

84%

OceanBase

環境配置

版本:社群版 3.1.4

元件

機器

OB Server

6臺機器,分成了3個zone,每個zone兩個UNIT。 每臺機器各部一個OB Server和一個OB Proxy

OB Proxy

租戶配置:

CREATE RESOURCE UNIT unit1 MAX_CPU 16, MAX_MEMORY '32G', MAX_IOPS 12800,MAX_DISK_SIZE '1000G', MAX_SESSION_NUM 6400, MIN_CPU=8, MIN_MEMORY='16G', MIN_IOPS=12800;
CREATE RESOURCE POOL pool1 UNIT='unit1',UNIT_NUM=2,ZONE_LIST=('zone1','zone2','zone3');
CREATE TENANT idx_test CHARSET='utf8mb4', ZONE_LIST=('zone1','zone2','zone3'), PRIMARY_ZONE='zone1;zone2,zone3', RESOURCE_POOL_LIST=('pool1') ;

需要注意的幾點:

  1. OB中的表預設為單表(只分布在一個節點上),需要使用分割槽表的語法,指定分割槽鍵與分割槽數,才能成為一張分散式表

  2. OB預設的索引是本地索引,需要指定Global關鍵字才是全域性索引

  3. OB的全域性索引預設也是一個單表(只有一個分割槽,只分布在一個節點上),需要手動指定分割槽數才是一個真正的分散式索引

  4. UNIT_NUM=1的情況下,似乎即使是分割槽表,也都在同一臺機器上,所以測試機器數要>=6,確保UNIT_NUM>=2

  5. OB全域性索引如果在建表語句中直接指定,似乎不支援指定分割槽數,因此全域性索引需要使用單獨的CREATE INDEX語句來建立

  6. OB分割槽表的AUTO_INCREMENT屬性似乎有嚴重的效能問題,設定了之後,效能很低,要去掉該屬性,並且將sysbench的auto_inc設為off,由sysbench來生成主鍵值

  7. OB預設使用的時間服務是本地時間服務(LTS),這種模式下是不支援全域性索引的,需要手動修改為全域性時間服務(GTS):

SET GLOBAL ob_timestamp_service='GTS';

測試結果

全域性索引:

索引數量

RT

(單執行緒)

最高TPS

TPS比例

0

1.40

72298

100%

1

2.56

18548

26%

2

2.81

13105

18%

4

3.38

9130

13%

8

3.91

5940

8%

本地索引:

索引數量

RT

(單執行緒)

最高TPS

TPS比例

0

1.40

72298

100%

1

1.41

63832

88%

2

1.37

62886

86%

4

1.45

61226

85%

8

1.47

56399

78%

TiDB

環境配置

版本:6.1.0

部署結構:

元件

機器

TiDB

5臺,每臺機器一個TiDB程序,一個TiKV程序

TiKV

PD

3臺

需要注意的點:

  1. TiDB中語法上沒有“全域性索引”這個詞,但從原理角度看,TiDB任何一張表都是分散式表,任何一個二級索引都是全域性索引,它沒有單表的概念。

  2. 不要使用AUTO_INCREMENT。TiDB中的AUTO_INCREMENT雖然是分段的,不保證自增連續,但拉長時間後依然是有一定時間序的,所以會導致熱點。需要使用AUTO_RANDOM替換AUTO_INCREMENT。

  3. TiDB中支援Partition語法,但其Partition依然構建於分散式KV之上,意味著每個Partition下面都對應著一個或多個TiKV中的range(注意,這裡的range和partition語法中的range是兩碼事,parition語法中的一個range,也可能對應多個TiKV中的range),這些range是會被自由的排程的。在使用了Partition語法的表上建立的索引,在功能上也叫區域性索引。

測試結果

全域性索引:

索引數量

RT

(單執行緒)

最高TPS

TPS比例

0

1.44

105112.07

100%

1

1.65

31876.11

30%

2

1.67

21631.28

20%

4

1.73

14045.03

13%

8

1.85

8138.60

8%

本地索引:

索引數量

RT

(單執行緒)

最高TPS

TPS比例

0

1.77

105521.21

100%

1

1.68

49534.19

47%

2

1.81

36861.78

35%

4

1.88

24788.64

23%

8

2.02

15776.30

15%

CockroachDB

環境配置

版本:22.1.6

元件

機器

CockroachDB

6臺,每臺機器一個CockroachDB程序

CDB與TiDB的架構是類似的,表構建於分散式KV之上,所有表都是分散式表,所有索引都是全域性索引,沒有單表的概念。

需要注意的點:

  1. 在CDB中,使用Serial型別主鍵(類似mysql中的auto_increment),或者使用unique_rowid()作為主鍵,因為這兩個都是有一定時間序的,都會產生顯著的熱點,幾乎無法使用。測試中使用UUID型別的列,並使用 gen_random_uuid()生成主鍵。這個本質是一個字串,在KV層range的劃分上可以認為是無序的。

  2. CDB每個連線的代價比較高,無法建立太多的連線。

測試結果

全域性索引:

索引數量

RT

(單執行緒)

最高TPS

TPS比例

0

2.75

86094

100%

1

2.81

13618

16%

2

2.81

11440

13%

4

3.41

9602

11%

8

5.83

7424 

9%

PolarDB-X

環境配置

規格:公有云8C32G*2

版本:5.4.13

注意:

  1. 建庫時需要使用mode=auto,這種型別的資料庫表不指定分割槽鍵的情況下是分散式表,同時索引是全域性索引。

  2. 索引前加Local關鍵字可以只建立Local索引。

測試結果

全域性索引:

索引數量

RT

(單執行緒)

最高TPS

TPS比例

0

1.06

71644.05

100%

1

2.22

20045.78

28%

2

2.25

13746.97

19%

4

3.07

10683.99

15%

8

3.67

8098.44

11%

本地索引:

索引數量

RT

(單執行緒)

最高TPS

TPS比例

0

1.06

71644.05

100%

1

1.34

69690.60

97%

2

1.35

67346.66

94%

4

1.47

64353.63

90%

8

1.5

58782.94

82%

06  附錄

OceanBase 全域性索引建表語句

create database sbtest_gsi8;
use sbtest_gsi8;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL,
`k` int(11) NOT NULL ,
`k1` int(11) NOT NULL ,
`k2` int(11) NOT NULL ,
`k3` int(11) NOT NULL ,
`k4` int(11) NOT NULL ,
`k5` int(11) NOT NULL ,
`k6` int(11) NOT NULL ,
`k7` int(11) NOT NULL ,
`k8` int(11) NOT NULL ,
`c` char(120) NOT NULL ,
`pad` char(60) NOT NULL ,
PRIMARY KEY (`id`)
) partition by hash(id) partitions 32;
create index k_1 on sbtest1(k1) global partition by hash(k1) partitions 32;
create index k_2 on sbtest1(k2) global partition by hash(k2) partitions 32;
create index k_3 on sbtest1(k3) global partition by hash(k3) partitions 32;
create index k_4 on sbtest1(k4) global partition by hash(k4) partitions 32;
create index k_5 on sbtest1(k5) global partition by hash(k5) partitions 32;
create index k_6 on sbtest1(k6) global partition by hash(k6) partitions 32;
create index k_7 on sbtest1(k7) global partition by hash(k7) partitions 32;
create index k_8 on sbtest1(k8) global partition by hash(k8) partitions 32;




create database sbtest_gsi4;
use sbtest_gsi4;


CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL,
`k` int(11) NOT NULL ,
`k1` int(11) NOT NULL ,
`k2` int(11) NOT NULL ,
`k3` int(11) NOT NULL ,
`k4` int(11) NOT NULL ,
`k5` int(11) NOT NULL ,
`k6` int(11) NOT NULL ,
`k7` int(11) NOT NULL ,
`k8` int(11) NOT NULL ,
`c` char(120) NOT NULL ,
`pad` char(60) NOT NULL ,
PRIMARY KEY (`id`)
) partition by hash(id) partitions 32;
create index k_1 on sbtest1(k1) global partition by hash(k1) partitions 32;
create index k_2 on sbtest1(k2) global partition by hash(k2) partitions 32;
create index k_3 on sbtest1(k3) global partition by hash(k3) partitions 32;
create index k_4 on sbtest1(k4) global partition by hash(k4) partitions 32;




create database sbtest_gsi2;
use sbtest_gsi2;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL,
`k` int(11) NOT NULL ,
`k1` int(11) NOT NULL ,
`k2` int(11) NOT NULL ,
`k3` int(11) NOT NULL ,
`k4` int(11) NOT NULL ,
`k5` int(11) NOT NULL ,
`k6` int(11) NOT NULL ,
`k7` int(11) NOT NULL ,
`k8` int(11) NOT NULL ,
`c` char(120) NOT NULL ,
`pad` char(60) NOT NULL ,
PRIMARY KEY (`id`)
) partition by hash(id) partitions 32;
create index k_1 on sbtest1(k1) global partition by hash(k1) partitions 32;
create index k_2 on sbtest1(k2) global partition by hash(k2) partitions 32;


create database sbtest_gsi1;
use sbtest_gsi1;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL ,
`k` int(11) NOT NULL ,
`k1` int(11) NOT NULL ,
`k2` int(11) NOT NULL ,
`k3` int(11) NOT NULL ,
`k4` int(11) NOT NULL ,
`k5` int(11) NOT NULL ,
`k6` int(11) NOT NULL ,
`k7` int(11) NOT NULL ,
`k8` int(11) NOT NULL ,
`c` char(120) NOT NULL ,
`pad` char(60) NOT NULL ,
PRIMARY KEY (`id`)
) partition by hash(id) partitions 32;
create index k_1 on sbtest1(k1) global partition by hash(k1) partitions 32;




create database sbtest_gsi0;
use sbtest_gsi0;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL ,
`k` int(11) NOT NULL ,
`k1` int(11) NOT NULL ,
`k2` int(11) NOT NULL ,
`k3` int(11) NOT NULL ,
`k4` int(11) NOT NULL ,
`k5` int(11) NOT NULL ,
`k6` int(11) NOT NULL ,
`k7` int(11) NOT NULL ,
`k8` int(11) NOT NULL ,
`c` char(120) NOT NULL ,
`pad` char(60) NOT NULL ,
PRIMARY KEY (`id`)
) partition by hash(id) partitions 32;

OceanBase 本地索引建表語句

create database sbtest_local8;
use sbtest_local8;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL,
`k` int(11) NOT NULL ,
`k1` int(11) NOT NULL ,
`k2` int(11) NOT NULL ,
`k3` int(11) NOT NULL ,
`k4` int(11) NOT NULL ,
`k5` int(11) NOT NULL ,
`k6` int(11) NOT NULL ,
`k7` int(11) NOT NULL ,
`k8` int(11) NOT NULL ,
`c` char(120) NOT NULL ,
`pad` char(60) NOT NULL ,
PRIMARY KEY (`id`)
) partition by hash(id) partitions 32;
create index k_1 on sbtest1(k1);
create index k_2 on sbtest1(k2);
create index k_3 on sbtest1(k3);
create index k_4 on sbtest1(k4);
create index k_5 on sbtest1(k5);
create index k_6 on sbtest1(k6);
create index k_7 on sbtest1(k7);
create index k_8 on sbtest1(k8);




create database sbtest_local4;
use sbtest_local4;


CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL,
`k` int(11) NOT NULL ,
`k1` int(11) NOT NULL ,
`k2` int(11) NOT NULL ,
`k3` int(11) NOT NULL ,
`k4` int(11) NOT NULL ,
`k5` int(11) NOT NULL ,
`k6` int(11) NOT NULL ,
`k7` int(11) NOT NULL ,
`k8` int(11) NOT NULL ,
`c` char(120) NOT NULL ,
`pad` char(60) NOT NULL ,
PRIMARY KEY (`id`)
) partition by hash(id) partitions 32;
create index k_1 on sbtest1(k1);
create index k_2 on sbtest1(k2);
create index k_3 on sbtest1(k3);
create index k_4 on sbtest1(k4);




create database sbtest_local2;
use sbtest_local2;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL,
`k` int(11) NOT NULL ,
`k1` int(11) NOT NULL ,
`k2` int(11) NOT NULL ,
`k3` int(11) NOT NULL ,
`k4` int(11) NOT NULL ,
`k5` int(11) NOT NULL ,
`k6` int(11) NOT NULL ,
`k7` int(11) NOT NULL ,
`k8` int(11) NOT NULL ,
`c` char(120) NOT NULL ,
`pad` char(60) NOT NULL ,
PRIMARY KEY (`id`)
) partition by hash(id) partitions 32;
create index k_1 on sbtest1(k1);
create index k_2 on sbtest1(k2);


create database sbtest_local1;
use sbtest_local1;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL ,
`k` int(11) NOT NULL ,
`k1` int(11) NOT NULL ,
`k2` int(11) NOT NULL ,
`k3` int(11) NOT NULL ,
`k4` int(11) NOT NULL ,
`k5` int(11) NOT NULL ,
`k6` int(11) NOT NULL ,
`k7` int(11) NOT NULL ,
`k8` int(11) NOT NULL ,
`c` char(120) NOT NULL ,
`pad` char(60) NOT NULL ,
PRIMARY KEY (`id`)
) partition by hash(id) partitions 32;
create index k_1 on sbtest1(k1);




create database sbtest_local0;
use sbtest_local0;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL ,
`k` int(11) NOT NULL ,
`k1` int(11) NOT NULL ,
`k2` int(11) NOT NULL ,
`k3` int(11) NOT NULL ,
`k4` int(11) NOT NULL ,
`k5` int(11) NOT NULL ,
`k6` int(11) NOT NULL ,
`k7` int(11) NOT NULL ,
`k8` int(11) NOT NULL ,
`c` char(120) NOT NULL ,
`pad` char(60) NOT NULL ,
PRIMARY KEY (`id`)
) partition by hash(id) partitions 32;

TiDB 全域性索引建表語句

create database sbtest8;
use sbtest8;
CREATE TABLE `sbtest1` (
`id` bigint(11) NOT NULL AUTO_RANDOM,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`),
KEY `k_2` (`k2`),
KEY `k_3` (`k3`),
KEY `k_4` (`k4`),
KEY `k_5` (`k5`),
KEY `k_6` (`k6`),
KEY `k_7` (`k7`),
KEY `k_8` (`k8`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;


create database sbtest4;
use sbtest4;
CREATE TABLE `sbtest1` (
`id` bigint(11) NOT NULL AUTO_RANDOM,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`),
KEY `k_2` (`k2`),
KEY `k_3` (`k3`),
KEY `k_4` (`k4`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;




create database sbtest2;
use sbtest2;
CREATE TABLE `sbtest1` (
`id` bigint(11) NOT NULL AUTO_RANDOM,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`),
KEY `k_2` (`k2`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;


create database sbtest1;
use sbtest1;
CREATE TABLE `sbtest1` (
`id` bigint(11) NOT NULL AUTO_RANDOM,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;




create database sbtest0;
use sbtest0;
CREATE TABLE `sbtest1` (
`id` bigint(11) NOT NULL AUTO_RANDOM,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;

TiDB 本地索引建表語句

create database sbtest_local8;
use sbtest_local8;
CREATE TABLE `sbtest1` (
`id` bigint(11) NOT NULL AUTO_RANDOM,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`),
KEY `k_2` (`k2`),
KEY `k_3` (`k3`),
KEY `k_4` (`k4`),
KEY `k_5` (`k5`),
KEY `k_6` (`k6`),
KEY `k_7` (`k7`),
KEY `k_8` (`k8`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 partition by hash(id) partitions 32;


create database sbtest_local4;
use sbtest_local4;
CREATE TABLE `sbtest1` (
`id` bigint(11) NOT NULL AUTO_RANDOM,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`),
KEY `k_2` (`k2`),
KEY `k_3` (`k3`),
KEY `k_4` (`k4`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 partition by hash(id) partitions 32;


create database sbtest_local2;
use sbtest_local2;
CREATE TABLE `sbtest1` (
`id` bigint(11) NOT NULL AUTO_RANDOM,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`),
KEY `k_2` (`k2`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 partition by hash(id) partitions 32;


create database sbtest_local1;
use sbtest_local1;
CREATE TABLE `sbtest1` (
`id` bigint(11) NOT NULL AUTO_RANDOM,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 partition by hash(id) partitions 32;


create database sbtest_local0;
use sbtest_local0;
CREATE TABLE `sbtest1` (
`id` bigint(11) NOT NULL AUTO_RANDOM,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 partition by hash(id) partitions 32;

PolarDB-X全域性索引建表語句

drop database sbtest_gsi0;
drop database sbtest_gsi1;
drop database sbtest_gsi2;
drop database sbtest_gsi4;
drop database sbtest_gsi8;
create database sbtest_gsi8 mode=auto;
use sbtest_gsi8;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`),
KEY `k_2` (`k2`),
KEY `k_3` (`k3`),
KEY `k_4` (`k4`),
KEY `k_5` (`k5`),
KEY `k_6` (`k6`),
KEY `k_7` (`k7`),
KEY `k_8` (`k8`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;


create database sbtest_gsi4 mode=auto;
use sbtest_gsi4;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`),
KEY `k_2` (`k2`),
KEY `k_3` (`k3`),
KEY `k_4` (`k4`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;




create database sbtest_gsi2 mode=auto;
use sbtest_gsi2;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`),
KEY `k_2` (`k2`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;


create database sbtest_gsi1 mode=auto;
use sbtest_gsi1;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k1`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;




create database sbtest_gsi0 mode=auto;
use sbtest_gsi0;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;

PolarDB-X本地索引建表語句

drop database sbtest_local0;
drop database sbtest_local1;
drop database sbtest_local2;
drop database sbtest_local4;
drop database sbtest_local8;
create database sbtest_local8 mode=auto;
use sbtest_local8;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
LOCAL KEY `k_1` (`k1`),
LOCAL KEY `k_2` (`k2`),
LOCAL KEY `k_3` (`k3`),
LOCAL KEY `k_4` (`k4`),
LOCAL KEY `k_5` (`k5`),
LOCAL KEY `k_6` (`k6`),
LOCAL KEY `k_7` (`k7`),
LOCAL KEY `k_8` (`k8`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;


create database sbtest_local4 mode=auto;
use sbtest_local4;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
LOCAL KEY `k_1` (`k1`),
LOCAL KEY `k_2` (`k2`),
LOCAL KEY `k_3` (`k3`),
LOCAL KEY `k_4` (`k4`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;




create database sbtest_local2 mode=auto;
use sbtest_local2;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
LOCAL KEY `k_1` (`k1`),
LOCAL KEY `k_2` (`k2`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;


create database sbtest_local1 mode=auto;
use sbtest_local1;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`k1` int(11) NOT NULL DEFAULT '0',
`k2` int(11) NOT NULL DEFAULT '0',
`k3` int(11) NOT NULL DEFAULT '0',
`k4` int(11) NOT NULL DEFAULT '0',
`k5` int(11) NOT NULL DEFAULT '0',
`k6` int(11) NOT NULL DEFAULT '0',
`k7` int(11) NOT NULL DEFAULT '0',
`k8` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
LOCAL KEY `k_1` (`k1`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;




create database sbtest_local0 mode=auto;
use sbtest_local0;
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;

CockroachDB全域性索引建表語句

drop database sbtest1 CASCADE;
drop database sbtest2 CASCADE;
drop database sbtest4 CASCADE;
drop database sbtest8 CASCADE;


create database sbtest0;
use sbtest0;
CREATE TABLE sbtest1 (
id UUID NOT NULL DEFAULT gen_random_uuid(),
k int NOT NULL ,
k1 int NOT NULL ,
k2 int NOT NULL ,
k3 int NOT NULL ,
k4 int NOT NULL ,
k5 int NOT NULL ,
k6 int NOT NULL ,
k7 int NOT NULL ,
k8 int NOT NULL ,
c char(120) NOT NULL ,
pad char(60) NOT NULL,
PRIMARY KEY (id)
);


create database sbtest1;
use sbtest1;
CREATE TABLE sbtest1 (
id UUID NOT NULL DEFAULT gen_random_uuid(),
k int NOT NULL ,
k1 int NOT NULL ,
k2 int NOT NULL ,
k3 int NOT NULL ,
k4 int NOT NULL ,
k5 int NOT NULL ,
k6 int NOT NULL ,
k7 int NOT NULL ,
k8 int NOT NULL ,
c char(120) NOT NULL ,
pad char(60) NOT NULL,
PRIMARY KEY (id),
INDEX k_1(k1)
);


create database sbtest2;
use sbtest2;
CREATE TABLE sbtest1 (
id UUID NOT NULL DEFAULT gen_random_uuid(),
k int NOT NULL ,
k1 int NOT NULL ,
k2 int NOT NULL ,
k3 int NOT NULL ,
k4 int NOT NULL ,
k5 int NOT NULL ,
k6 int NOT NULL ,
k7 int NOT NULL ,
k8 int NOT NULL ,
c char(120) NOT NULL ,
pad char(60) NOT NULL,
PRIMARY KEY (id),
INDEX k_1(k1),
INDEX k_2(k2)
);


create database sbtest4;
use sbtest4;
CREATE TABLE sbtest1 (
id UUID NOT NULL DEFAULT gen_random_uuid(),
k int NOT NULL ,
k1 int NOT NULL ,
k2 int NOT NULL ,
k3 int NOT NULL ,
k4 int NOT NULL ,
k5 int NOT NULL ,
k6 int NOT NULL ,
k7 int NOT NULL ,
k8 int NOT NULL ,
c char(120) NOT NULL ,
pad char(60) NOT NULL,
PRIMARY KEY (id),
INDEX k_1(k1),
INDEX k_2(k2),
INDEX k_3(k3),
INDEX k_4(k4)
);


create database sbtest8;
use sbtest8;
CREATE TABLE sbtest1 (
id UUID NOT NULL DEFAULT gen_random_uuid(),
k int NOT NULL ,
k1 int NOT NULL ,
k2 int NOT NULL ,
k3 int NOT NULL ,
k4 int NOT NULL ,
k5 int NOT NULL ,
k6 int NOT NULL ,
k7 int NOT NULL ,
k8 int NOT NULL ,
c char(120) NOT NULL ,
pad char(60) NOT NULL,
PRIMARY KEY (id),
INDEX k_1(k1),
INDEX k_2(k2),
INDEX k_3(k3),
INDEX k_4(k4),
INDEX k_5(k5),
INDEX k_6(k6),
INDEX k_7(k7),
INDEX k_8(k8)
);

/ End /  

推薦閱讀

點選 「閱讀原文」 檢視 PolarDB-X 更多技術乾貨