Secara default, ApsaraDB for SelectDB menggunakan penyimpanan kolom. Pada tabel lebar, pendekatan ini meningkatkan I/O baca acak saat mengambil satu baris, sehingga memperlambat kueri titik. Selain itu, antarmuka depan (FE) yang ditulis dalam Java mengalami beban CPU tinggi akibat penguraian volume besar kueri SQL konkuren. Untuk mengatasi masalah tersebut, SelectDB menyediakan tiga mekanisme saling melengkapi—penyimpanan baris (row store), jalur kueri pendek, dan prepared statements—yang secara signifikan mengurangi latensi kueri titik dengan konkurensi tinggi.
Cara kerja
| Mekanisme | Fungsinya |
|---|---|
| Row store | Menyimpan salinan setiap baris dalam format baris, sehingga menghilangkan I/O per kolom untuk kueri titik |
| Short query path | Memungkinkan pengoptimal kueri melewati mesin eksekusi standar dan menyelesaikan pencarian berdasarkan primary key dengan satu panggilan prosedur remote (RPC) |
| Prepared statements | Menyimpan cache SQL dan ekspresi yang telah diurai pada tingkat sesi di FE, sehingga menghilangkan beban penguraian berulang pada beban kerja dengan konkurensi tinggi |
Kapan menggunakan row store
Row store memerlukan ruang penyimpanan tambahan. Gunakan tabel berikut untuk menentukan apakah fitur ini perlu diaktifkan.
| Skenario | Penyimpanan yang direkomendasikan | Rekomendasi |
|---|---|---|
| Pencarian primary key dengan konkurensi tinggi | Row store | Aktifkan row store + merge on write (MoW) |
| Agregasi kompleks dan JOIN multi-tabel pada tabel lebar | Column store | Pertahankan column store default |
| Beban kerja campuran (kueri titik + analitik) | Keduanya | Aktifkan row store secara selektif |
Aktifkan row store
Row store harus diaktifkan saat pembuatan tabel. Tambahkan properti berikut ke pernyataan CREATE TABLE:
"store_row_column" = "true"Row store tidak dapat diaktifkan atau dinonaktifkan setelah tabel dibuat.
Optimalkan kueri titik pada model Unique Key
Jika kedua properti enable_unique_key_merge_on_write dan store_row_column diatur ke true pada tabel model Unique Key, pengoptimal kueri akan mengaktifkan jalur kueri pendek untuk kueri titik berbasis primary key. Dalam hal ini, hanya diperlukan satu RPC untuk mengeksekusi kueri tersebut.
Contoh berikut menunjukkan pembuatan tabel dengan row store dan MoW diaktifkan:
CREATE TABLE `tbl_point_query` (
`key` int(11) NULL,
`v1` decimal(27, 9) NULL,
`v2` varchar(30) NULL,
`v3` varchar(30) NULL,
`v4` date NULL,
`v5` datetime NULL,
`v6` float NULL,
`v7` datev2 NULL
) ENGINE=OLAP
UNIQUE KEY(`key`)
COMMENT 'OLAP'
DISTRIBUTED BY HASH(`key`) BUCKETS 16
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"light_schema_change" = "true",
"store_row_column" = "true"
);| Properti | Nilai | Tujuan |
|---|---|---|
enable_unique_key_merge_on_write | true | Mengaktifkan MoW agar mesin penyimpanan dapat dengan cepat menemukan baris berdasarkan primary key |
store_row_column | true | Mengaktifkan row store untuk pengambilan seluruh baris yang cepat |
light_schema_change | true | Diperlukan untuk jalur kueri pendek; pengoptimal menggunakan ID kolom unik dari lightweight schema change untuk menemukan kolom |
Jalur kueri pendek hanya berlaku jika klausa WHERE berisi kondisi kesamaan pada kolom kunci dari satu tabel, contohnya:
SELECT * FROM tbl_point_query WHERE key = 123;Gunakan prepared statements
Prepared statements sepenuhnya kompatibel dengan protokol MySQL. Ketika diaktifkan di FE, SelectDB mengurai setiap pernyataan SQL beserta ekspresinya hanya sekali, lalu menyimpan hasilnya dalam memori tingkat sesi. Eksekusi berikutnya menggunakan kembali objek yang telah di-cache, sehingga proses penguraian dapat dilewati sepenuhnya. Untuk kueri titik berbasis primary key yang dibatasi oleh CPU, pendekatan ini dapat meningkatkan throughput lebih dari empat kali lipat.
Prepared statements hanya berfungsi untuk kueri titik berbasis primary key.
Aktifkan prepared statements melalui Java Database Connectivity (JDBC):
Tambahkan
useServerPrepStmts=trueke URL JDBC:jdbc:mysql://127.0.0.1:9030/ycsb?useServerPrepStmts=truePersiapkan statement sekali dan gunakan kembali objek
PreparedStatementdi berbagai kueri:// Gunakan ? sebagai placeholder. Gunakan kembali readStatement di beberapa kueri. PreparedStatement readStatement = conn.prepareStatement( "SELECT * FROM tbl_point_query WHERE key = ?" ); readStatement.setInt(1, 1234); ResultSet resultSet = readStatement.executeQuery(); // Gunakan kembali statement yang sama untuk kueri berikutnya readStatement.setInt(1, 1235); resultSet = readStatement.executeQuery();
Aktifkan row cache
SelectDB menyertakan page cache yang menyimpan data per kolom—setiap halaman berisi data satu kolom. Dalam mode row store, satu halaman menyimpan data dari beberapa kolom, sehingga lebih rentan terhadap penggantian oleh kueri analitik besar, yang mengurangi tingkat hit cache.
Row cache mengatasi masalah ini dengan menyediakan cache tingkat baris khusus yang menerapkan kebijakan penggantian least recently used (LRU), sehingga menjaga baris yang sering diakses tetap berada di memori meskipun terjadi persaingan ruang cache dari kueri analitik besar.
Konfigurasikan row cache di pengaturan backend (BE):
| Parameter | Default | Deskripsi |
|---|---|---|
disable_storage_row_cache | false | Mengontrol ketersediaan row cache. Default-nya false, yang berarti row cache tetap aktif. Atur ke true untuk menonaktifkan row cache dan mengurangi beban memori. |
row_cache_mem_limit | 20 | Persentase maksimum memori yang dialokasikan untuk row cache. Default-nya 20%. |
Batasan
Row store hanya dapat diaktifkan saat pembuatan tabel. Modifikasi pada tabel yang sudah ada tidak didukung.
Jalur kueri pendek hanya berlaku untuk kondisi kesamaan (
=) pada kolom kunci dari satu tabel. Kueri JOIN dan subkueri bersarang tidak didukung.Klausa
WHEREharus hanya merujuk pada kolom kunci (kueri pasangan kunci-nilai).Prepared statements hanya berfungsi untuk kueri titik berbasis primary key.
light_schema_change = truediperlukan agar jalur kueri pendek berfungsi dengan benar.