Pada tabel terdistribusi PolarDB-X, kueri yang tidak menyertakan kunci partisi memicu pemindaian penuh di seluruh node data. Hal ini menurunkan performa hingga batas maksimum node tunggal dan menghilangkan skalabilitas linear. Global secondary index (GSI) menghindari pemindaian partisi penuh dengan memungkinkan Anda menentukan skema partisi independen untuk indeks—sehingga kolom apa pun dapat menjadi jalur kueri yang efisien.
Cara kerja GSIs
PolarDB-X menyimpan data tabel di beberapa node data, dipartisi berdasarkan kunci tertentu. Kueri yang menyertakan kunci partisi langsung diarahkan ke partisi yang relevan, sedangkan kueri yang tidak menyertakannya disebar ke setiap partisi.
Jika sistem memiliki N node data, kueri berbasis kunci partisi memberikan beban rata-rata sebesar 1/N pada setiap node. Sebaliknya, pemindaian partisi penuh memberikan beban sebesar 1 pada setiap node—sehingga batas performa turun ke tingkat node tunggal dan sistem kehilangan skalabilitas linear.
GSI mengatasi hal ini dengan bertindak sebagai tabel terpartisi khusus yang menduplikasi kolom tertentu dari tabel utama. Tabel ini dipartisi secara horizontal berdasarkan kunci yang ditentukan pengguna, yang berbeda dari kunci partisi tabel utama. Ketika kueri sesuai dengan kunci partisi GSI, PolarDB-X mengarahkannya ke partisi GSI yang relevan, mengambil baris yang cocok, lalu mengambil kolom tambahan apa pun dari tabel utama. Pendekatan ini menghindari pemindaian partisi penuh.
PolarDB-X menggunakan transaksi terdistribusi untuk menjaga konsistensi data kuat antara tabel utama dan GSIs-nya.
GSI juga mendukung:
Online DDL — membuat, memodifikasi, dan menghapus GSI tanpa mengunci tabel
Custom covering columns — menyimpan kolom tambahan dalam GSI untuk mengurangi atau menghilangkan lookup ke tabel utama
Invisible indexes — menguji dampak GSI terhadap rencana kueri tanpa mengeksposnya ke pengoptimal kueri, sehingga Anda dapat memvalidasi performa indeks sebelum mengaktifkannya di lingkungan produksi
Jenis GSI
GSI
GSI standar mempartisi data indeks berdasarkan kolom selain kunci partisi tabel utama. Ketika kueri sesuai dengan kunci partisi GSI, PolarDB-X mengarahkan kueri ke partisi yang relevan dan melakukan lookup ke tabel utama untuk kolom tambahan yang diperlukan.
Example: Tabel user dipartisi berdasarkan user_id. Untuk mendukung kueri efisien berdasarkan name, buat GSI pada name.
CREATE TABLE user(
user_id bigint,
name varchar(10),
addr varchar(30),
GLOBAL INDEX `g_i_name` (name) PARTITION BY HASH(name),
PRIMARY KEY(user_id)
) PARTITION BY KEY(user_id);Dengan adanya g_i_name, kueri yang difilter berdasarkan name diarahkan ke partisi yang sesuai pada indeks, bukan memindai semua partisi user.
UGSI
Unique global secondary index (UGSI) memiliki semua properti GSI standar dan juga menerapkan kendala UNIQUE global di seluruh tabel terdistribusi.
Contoh: Tabel user2 dipartisi berdasarkan user_id. Untuk menjamin bahwa phone bersifat unik secara global di semua partisi, buat UGSI pada phone.
CREATE TABLE user2(
user_id bigint,
phone varchar(20),
addr varchar(30),
UNIQUE GLOBAL INDEX `g_i_phone`(phone) PARTITION BY HASH(phone),
PRIMARY KEY(user_id)
) PARTITION BY KEY(user_id);Clustered GSI
Secara default, clustered GSI menyimpan semua kolom dari tabel utama—bukan hanya kunci indeks dan kolom covering. Karena semua kolom tersedia di indeks, kueri tidak perlu lagi melakukan lookup ke tabel utama, sehingga overhead lookup sepenuhnya dihilangkan.
Imbalannya: clustered GSI menempati ruang disk yang sama dengan tabel utama.
Contoh: Tabel order_tbl dipartisi berdasarkan order_id. Untuk mendukung kueri cepat berdasarkan user_id tanpa lookup ke tabel utama, buat clustered GSI pada user_id.
CREATE TABLE order_tbl(
order_id bigint,
user_id bigint,
addr varchar(30),
info text,
create_time datetime,
CLUSTERED INDEX `cg_i_user`(user_id) PARTITION BY HASH(user_id),
PRIMARY KEY(order_id)
) PARTITION BY KEY(order_id);Saat melakukan kueri berdasarkan user_id, PolarDB-X mengarahkan kueri ke partisi yang sesuai pada cg_i_user dan membaca semua data yang diperlukan langsung dari indeks.
Kapan menggunakan masing-masing jenis
| Skenario | Jenis yang direkomendasikan |
|---|---|
| Kueri berdasarkan kolom non-partisi; lookup ke tabel utama dapat diterima | GSI |
| Kueri berdasarkan kolom non-partisi; kolom harus unik secara global | UGSI |
| Kueri berdasarkan kolom non-partisi; prioritas utama adalah menghilangkan overhead lookup | Clustered GSI |
Performa
GSI meningkatkan performa baca tetapi menurunkan performa tulis. Benchmark Sysbench berikut menggambarkan dampaknya pada skala besar.
Performa baca
| Tabel | Threads | select_random_ranges QPS | Rata-rata latensi (ms) | Persentil ke-95 (ms) | select_random_points QPS | Rata-rata latensi (ms) | Persentil ke-95 (ms) |
|---|---|---|---|---|---|---|---|
| Tabel partisi | 128 | 2.769,17 | 46,21 | 99,33 | 5.226,99 | 24,48 | 42,61 |
| 256 | 3.415,64 | 144,97 | 144,97 | 5.476,76 | 46,73 | 82,96 | |
| 512 | 3.272,46 | 156,31 | 257,95 | 5.290,67 | 96,72 | 179,94 | |
| 1.024 | 2.453,16 | 416,12 | 539,71 | 5.165,31 | 198,07 | 404,61 | |
| Tabel partisi + GSI | 128 | 9.662,11 | 13,24 | 25,28 | 22.584,89 | 5,66 | 9,73 |
| 256 | 10.431,73 | 24,52 | 51,02 | 25.558,26 | 10,01 | 17,95 | |
| 512 | 15.634,51 | 32,72 | 73,13 | 27.116,56 | 18,86 | 39,65 | |
| 1.024 | 22.948,76 | 44,53 | 108,68 | 32.509,87 | 31,43 | 73,13 |
Dengan GSI pada kolom indeks:
QPS kueri rentang: 3.415,64 → 22.948,76 — 571% improvement
QPS kueri titik: 5.476,76 → 32.509,87 — 493% improvement
Performa tulis
| Tabel | Threads | Write-only QPS | Rata-rata latensi (ms) | Persentil ke-95 (ms) | Read-write QPS | Rata-rata latensi (ms) | Persentil ke-95 (ms) |
|---|---|---|---|---|---|---|---|
| Tabel partisi | 128 | 86.548,12 | 8,87 | 10,27 | 113.655,28 | 22,52 | 26,2 |
| 256 | 115.774,71 | 13,26 | 19,29 | 149.677,52 | 34,19 | 44,17 | |
| 512 | 143.928,94 | 20,51 | 34,95 | 14.555,16 | 70,28 | 112,67 | |
| 1.024 | 153.501,7 | 39,53 | 70,55 | 132.150,69 | 131,58 | 287,38 | |
| Tabel partisi + GSI | 128 | 52.069,22 | 14,25 | 18,28 | 90.074,59 | 28,41 | 33,72 |
| 256 | 66.250,79 | 23,17 | 32,53 | 114.420,32 | 44,73 | 57,87 | |
| 512 | 75.700,74 | 39,1 | 59,99 | 111.093,61 | 92,09 | 142,39 | |
| 1.024 | 76.557,94 | 80,14 | 134,9 | 101.828,32 | 182,51 | 350,33 |
Dengan GSI pada kolom indeks:
QPS write-only: 153.501,7 → 76.557,94 — 50% reduction
QPS read-write campuran: 149.677,52 → 114.420,32 — 23% reduction