Topik ini menjelaskan proses pengurutan data indeks penyimpanan kolom, cara menggunakan fitur tersebut, serta membandingkan waktu pembuatan dan kueri terhadap data indeks penyimpanan kolom yang telah diurutkan.
Pendahuluan
Data indeks penyimpanan kolom diorganisasi berdasarkan grup baris. Secara default, setiap grup baris berisi 64.000 baris. Di dalam setiap grup baris, kolom-kolom yang berbeda dikemas ke dalam blok data kolom. Blok-blok ini dibangun secara paralel berdasarkan urutan kunci primer dari data penyimpanan baris asli. Karena data yang diperbarui ditulis dalam urutan tambahan (append order), data tersebut umumnya tidak terurut.
Indeks penyimpanan kolom mendukung indeks kasar. Metadata setiap blok data kolom mencakup informasi seperti nilai minimum dan maksimum dari seluruh data dalam blok tersebut. Saat melakukan kueri, semua blok data kolom dari kolom tertentu biasanya dilalui (traversed). Setelah Pemangkas IMCI diaktifkan, semua blok data kolom diklasifikasikan ke dalam tiga kategori berdasarkan kondisi kueri dan metadata: relevan, mungkin relevan, dan tidak relevan. Hanya blok data kolom yang relevan dan mungkin relevan yang dibaca. Susunan blok data kolom dapat diatur dalam urutan berbeda, menghasilkan kombinasi koleksi blok yang berbeda dan memengaruhi efisiensi pemfilteran oleh Pemangras IMCI. Oleh karena itu, Anda dapat mengatur susunan blok data kolom berdasarkan kondisi kueri untuk meningkatkan kinerja kueri.
Seperti yang ditunjukkan pada gambar sebelumnya, ketika pernyataan SQL berikut dieksekusi pada kumpulan blok data yang tidak terurut, semua blok data kolom harus dimuat dan diproses. Untuk kumpulan blok data yang terurut, blok data kolom pertama dapat difilter berdasarkan nilai maksimum dan minimum dalam metadatanya, sehingga hanya blok data kolom kedua yang perlu diproses.
SELECT * FROM t WHERE c >= 8;Kesesuaian
Untuk menggunakan fitur Pengurutan data saat membuat indeks penyimpanan kolom baru, Anda memerlukan kluster Edisi Perusahaan yang memenuhi salah satu persyaratan berikut:
PolarDB for MySQL 8.0.1 dengan versi revisi 8.0.1.1.32 atau lebih baru.
PolarDB for MySQL 8.0.2 dengan versi revisi 8.0.2.2.12 atau lebih baru.
Untuk menggunakan fitur Pengurutan data inkremental, Anda memerlukan kluster Edisi Perusahaan yang memenuhi salah satu persyaratan berikut:
PolarDB for MySQL 8.0.1 dengan versi revisi 8.0.1.1.39.1 atau lebih baru.
PolarDB for MySQL 8.0.2 dengan versi revisi 8.0.2.2.20.1 atau lebih baru.
Anda dapat memeriksa versi kluster. Untuk informasi selengkapnya, lihat Kueri nomor versi.
Perhatian
Kolom dengan tipe data BLOB, JSON, atau GEOMETRY tidak dapat digunakan sebagai kunci pengurutan.
Fitur pengurutan data inkremental tidak mendukung kunci pengurutan dengan tipe data integer tak bertanda (unsigned integer) atau Decimal.
Pengurutan inkremental hanya mempertahankan urutan berdasarkan kolom pertama dari kunci pengurutan.
Pengurutan data inkremental mengonsumsi sejumlah sumber daya tertentu. Oleh karena itu, ketika beban kerja penulisan (write workload) kluster tinggi, kecepatan pengurutan data inkremental melambat untuk melepaskan lebih banyak sumber daya bagi operasi penulisan data.
Prosedur pengurutan
Prosedur pengurutan data saat membuat indeks penyimpanan kolom baru
Pengurutan data untuk indeks penyimpanan kolom diimplementasikan dengan cara yang mirip dengan algoritma pengurutan untuk indeks sekunder selama proses Data Definition Language (DDL). Pengurutan single-threaded maupun multi-threaded didukung. Pengurutan single-threaded menggunakan pengurutan penggabungan dua arah standar. Pengurutan multi-threaded menggunakan k-way external merge sort dengan pohon loser dan mendukung kebijakan pengurutan pengambilan sampel. Proses keseluruhan adalah sebagai berikut:
Lalui (traverse) data berdasarkan indeks kunci primer dan simpan data lengkap yang dibaca ke file data. Kemudian, tambahkan kolom kunci pengurutan ke buffer pengurutan. Setiap thread menggunakan file data yang berbeda dan menulis data setelah jumlah tertentu terkumpul.
Lanjutkan melalui dan memasukkan data ke dalam buffer pengurutan. Ketika buffer pengurutan penuh, urutkan data di memori berdasarkan kombinasi kunci pengurutan dan simpan data ke file penggabungan (merge files).
Setelah traversal selesai, urutkan file penggabungan segmen demi segmen secara berpasangan. Simpan data yang telah diurutkan ke file sementara, lalu ganti file penggabungan dengan file sementara tersebut.
Ulangi Langkah 3 hingga file penggabungan diurutkan. Kemudian, baca setiap catatan dalam file penggabungan, ambil catatan yang sesuai dari file data berdasarkan nilai offset, dan tambahkan ke indeks penyimpanan kolom.
Prosedur pengurutan data inkremental
Proses pengurutan untuk data inkremental bersifat progresif dan tidak menjamin bahwa data sepenuhnya terurut. Proses keseluruhan adalah sebagai berikut:
Kelompokkan semua blok data secara berpasangan dan pilih beberapa kelompok blok data dengan tingkat tumpang tindih yang tinggi dalam rentang waktu (timestamp range)-nya.
Lakukan pengurutan gabungan (merge sort) pada setiap kelompok blok data untuk menghasilkan dua blok data terurut baru.
Ulangi Langkah 2 hingga semua blok data diurutkan.
Deskripsi parameter
Anda harus mengatur parameter dalam tabel berikut di database untuk mengaktifkan atau menonaktifkan fitur pengurutan indeks penyimpanan kolom dan mengonfigurasi jumlah thread sesuai kebutuhan.
Metode untuk memodifikasi parameter kluster PolarDB berbeda tergantung pada apakah Anda menggunakan konsol atau sesi database. Perbedaannya adalah sebagai berikut:
Kompatibilitas: Beberapa parameter kluster di Konsol PolarDB menggunakan awalan loose_ untuk menjaga kompatibilitas dengan file konfigurasi MySQL.
Prosedur: Temukan dan modifikasi parameter yang memiliki awalan
loose_.
Dalam sesi database (menggunakan command line atau klien):
Prosedur: Saat Anda terhubung ke database dan menggunakan perintah
SETuntuk memodifikasi parameter, hapus awalanloose_dan gunakan nama parameter aslinya.
Parameter | Deskripsi |
loose_imci_enable_pack_order_key | Mengontrol apakah akan mengurutkan data saat membuat indeks penyimpanan kolom baru. Nilai yang valid:
|
loose_imci_enable_pack_order_key_changed_rebuild | Menentukan apakah tabel perlu dibangun ulang saat urutan pengurutan indeks penyimpanan kolom berubah. Nilai yang valid:
|
loose_imci_parallel_build_threads_per_table | Jumlah thread yang digunakan untuk membangun data indeks penyimpanan kolom untuk satu tabel. Rentang nilai: 1 hingga 128. Nilai default: 8. |
Catatan penggunaan
Anda dapat menggunakan fitur pengurutan data indeks penyimpanan kolom dengan mengikuti langkah-langkah berikut:
Aktifkan fitur pengurutan indeks penyimpanan kolom.
Atur parameter
imci_enable_pack_order_keyke ON untuk mengaktifkan fitur Pengurutan data saat membuat indeks penyimpanan kolom baru.Tambahkan properti
order_keykecommentpada pernyataan SQL berikut untuk membangun data indeks penyimpanan kolom yang terurut.ALTER TABLE table_name COMMENT 'columnar=1 order_key=column_name[,column_name]';Deskripsi parameter:
Parameter
Deskripsi
table_name
Nama tabel.
column_name
Nama kolom. Anda dapat mengonfigurasi beberapa nama kolom. Pisahkan beberapa nama kolom dengan koma (,).
Anda dapat memantau kemajuan pembuatan IMCI di tabel
INFORMATION_SCHEMA.IMCI_ASYNC_DDL_STATS. Untuk informasi selengkapnya tentang tabelINFORMATION_SCHEMA.IMCI_ASYNC_DDL_STATS, lihat Lihat kecepatan eksekusi DDL dan kemajuan pembuatan IMCI.
SELECT * FROM INFORMATION_SCHEMA.IMCI_ASYNC_DDL_STATS;Differences Between Columnstore Index Data Sorting And DDL Sorting
Pengurutan data indeks penyimpanan kolom pada dasarnya adalah pengurutan berdasarkan kombinasi kunci tertentu, yang mirip dengan proses pengurutan DDL untuk indeks sekunder lainnya. Namun, keduanya berbeda dalam aspek-aspek berikut:
Pengurutan indeks penyimpanan kolom tidak menggunakan kolom indeks sebagai kunci pengurutan. Sebaliknya, Anda dapat menentukan kombinasi kolom apa pun sebagai kunci pengurutan.
Setelah pengurutan indeks penyimpanan kolom, data lengkap harus dibaca. Untuk DDL indeks sekunder, hanya bagian indeks dari data yang perlu disimpan. Misalnya, untuk bidang VARCHAR, hanya awalannya yang disimpan sebagai data indeks.
Perbandingan waktu pembuatan dan kueri untuk data indeks penyimpanan kolom yang diurutkan
Contoh ini menggunakan dataset TPC-H 100 GB untuk menguji waktu yang diperlukan untuk membangun dan melakukan kueri terhadap data indeks penyimpanan kolom yang diurutkan.
Uji waktu pembuatan data indeks penyimpanan kolom yang diurutkan.
Contoh ini membangun data indeks penyimpanan kolom yang diurutkan untuk tabel
lineitemdengan 16 thread paralel. Berikut adalah contoh pernyataan:ALTER TABLE lineitem COMMENT='columnar=1 order_key=l_receiptdate,l_shipmode';Waktu pembuatan adalah sebagai berikut:
Dataset tidak terurut
Dataset terurut
6 menit
35 menit
Uji waktu kueri data indeks penyimpanan kolom yang diurutkan.
Contoh ini menjalankan kueri TPC-H Q12. Cache Least Recently Used (LRU) dan memori pelaksana (executor) keduanya diatur menjadi 10 GB. Berikut adalah pernyataan kuerinya:
SELECT l_shipmode, SUM(CASE WHEN o_orderpriority = '1-URGENT' OR o_orderpriority = '2-HIGH' THEN 1 ELSE 0 END) AS high_line_count, SUM(CASE WHEN o_orderpriority <> '1-URGENT' AND o_orderpriority <> '2-HIGH' THEN 1 ELSE 0 END) AS low_line_count FROM orders, lineitem WHERE o_orderkey = l_orderkey AND l_shipmode in ('MAIL', 'SHIP') AND l_commitdate < l_receiptdate AND l_shipdate < l_commitdate AND l_receiptdate >= date '1994-01-01' AND l_receiptdate < date '1994-01-01' + interval '1' year GROUP BY l_shipmode ORDER BY l_shipmode;Waktu kueri adalah sebagai berikut:
Dataset tidak terurut
Dataset terurut
7,47 detik
1,25 detik
Perbandingan waktu kueri dengan kunci pengurutan dan tabel partisi
Pengujian ini menggunakan dataset TPC-H 1 TB pada node dengan 32 core dan memori 256 GB. Pengujian ini menguji kinerja kueri saat fitur indeks penyimpanan kolom diaktifkan (column store) dan saat fitur indeks penyimpanan kolom diaktifkan dengan partisi dan kolom kunci pengurutan.
Pernyataan pembuatan tabel standar berikut digunakan untuk pengujian:
CREATE TABLE region ( r_regionkey BIGINT NOT NULL,
r_name CHAR(25) NOT NULL,
r_comment VARCHAR(152)) COMMENT 'COLUMNAR=1';
CREATE TABLE nation ( n_nationkey BIGINT NOT NULL,
n_name CHAR(25) NOT NULL,
n_regionkey BIGINT NOT NULL,
n_comment VARCHAR(152)) COMMENT 'COLUMNAR=1';
CREATE TABLE part ( p_partkey BIGINT NOT NULL,
p_name VARCHAR(55) NOT NULL,
p_mfgr CHAR(25) NOT NULL,
p_brand CHAR(10) NOT NULL,
p_type VARCHAR(25) NOT NULL,
p_size BIGINT NOT NULL,
p_container CHAR(10) NOT NULL,
p_retailprice DECIMAL(15,2) NOT NULL,
p_comment VARCHAR(23) NOT NULL) COMMENT 'COLUMNAR=1';
CREATE TABLE supplier ( s_suppkey BIGINT NOT NULL,
s_name CHAR(25) NOT NULL,
s_address VARCHAR(40) NOT NULL,
s_nationkey BIGINT NOT NULL,
s_phone CHAR(15) NOT NULL,
s_acctbal DECIMAL(15,2) NOT NULL,
s_comment VARCHAR(101) NOT NULL) COMMENT 'COLUMNAR=1';
CREATE TABLE partsupp ( ps_partkey BIGINT NOT NULL,
ps_suppkey BIGINT NOT NULL,
ps_availqty BIGINT NOT NULL,
ps_supplycost DECIMAL(15,2) NOT NULL,
ps_comment VARCHAR(199) NOT NULL) COMMENT 'COLUMNAR=1';
CREATE TABLE customer ( c_custkey BIGINT NOT NULL,
c_name VARCHAR(25) NOT NULL,
c_address VARCHAR(40) NOT NULL,
c_nationkey BIGINT NOT NULL,
c_phone CHAR(15) NOT NULL,
c_acctbal DECIMAL(15,2) NOT NULL,
c_mktsegment CHAR(10) NOT NULL,
c_comment VARCHAR(117) NOT NULL) COMMENT 'COLUMNAR=1';
CREATE TABLE orders ( o_orderkey BIGINT NOT NULL,
o_custkey BIGINT NOT NULL,
o_orderstatus CHAR(1) NOT NULL,
o_totalprice DECIMAL(15,2) NOT NULL,
o_orderdate DATE NOT NULL,
o_orderpriority CHAR(15) NOT NULL,
o_clerk CHAR(15) NOT NULL,
o_shippriority BIGINT NOT NULL,
o_comment VARCHAR(79) NOT NULL) COMMENT 'COLUMNAR=1'
PARTITION BY RANGE (year(`o_orderdate`))
(PARTITION p0 VALUES LESS THAN (1992) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (1993) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (1994) ENGINE = InnoDB,
PARTITION p3 VALUES LESS THAN (1995) ENGINE = InnoDB,
PARTITION p4 VALUES LESS THAN (1996) ENGINE = InnoDB,
PARTITION p5 VALUES LESS THAN (1997) ENGINE = InnoDB,
PARTITION p6 VALUES LESS THAN (1998) ENGINE = InnoDB,
PARTITION p7 VALUES LESS THAN (1999) ENGINE = InnoDB);
CREATE TABLE lineitem ( l_orderkey BIGINT NOT NULL,
l_partkey BIGINT NOT NULL,
l_suppkey BIGINT NOT NULL,
l_linenumber BIGINT NOT NULL,
l_quantity DECIMAL(15,2) NOT NULL,
l_extendedprice DECIMAL(15,2) NOT NULL,
l_discount DECIMAL(15,2) NOT NULL,
l_tax DECIMAL(15,2) NOT NULL,
l_returnflag CHAR(1) NOT NULL,
l_linestatus CHAR(1) NOT NULL,
l_shipdate DATE NOT NULL,
l_commitdate DATE NOT NULL,
l_receiptdate DATE NOT NULL,
l_shipinstruct CHAR(25) NOT NULL,
l_shipmode CHAR(10) NOT NULL,
l_comment VARCHAR(44) NOT NULL) COMMENT 'COLUMNAR=1'
PARTITION BY RANGE (year(`l_shipdate`))
(PARTITION p0 VALUES LESS THAN (1992) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (1993) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (1994) ENGINE = InnoDB,
PARTITION p3 VALUES LESS THAN (1995) ENGINE = InnoDB,
PARTITION p4 VALUES LESS THAN (1996) ENGINE = InnoDB,
PARTITION p5 VALUES LESS THAN (1997) ENGINE = InnoDB,
PARTITION p6 VALUES LESS THAN (1998) ENGINE = InnoDB,
PARTITION p7 VALUES LESS THAN (1999) ENGINE = InnoDB);Setelah data diimpor, atur kolom kunci pengurutan untuk tabel-tabel tersebut. Untuk informasi selengkapnya, lihat Konfigurasikan kunci pengurutan untuk indeks penyimpanan kolom.
ALTER TABLE customer COMMENT='COLUMNAR=1 order_key=c_mktsegment';
ALTER TABLE nation COMMENT='COLUMNAR=1 order_key=n_name';
ALTER TABLE part COMMENT='COLUMNAR=1 order_key=p_brand,p_container,p_type';
ALTER TABLE region COMMENT='COLUMNAR=1 order_key=r_name';
ALTER TABLE orders COMMENT='COLUMNAR=1 order_key=o_orderkey,o_custkey,o_orderdate';
ALTER TABLE lineitem COMMENT='COLUMNAR=1 order_key=l_orderkey,l_linenumber,l_receiptdate,l_shipdate,l_partkey';Sejumlah pernyataan kueri TPC-H dipilih untuk pengujian. Waktu kueri ditampilkan dalam tabel berikut:
Kueri SQL | Dataset tidak terurut (detik) | Dataset terurut (dengan partisi dan kolom kunci pengurutan) (detik) |
Q3 | 71,951 | 36,566 |
Q4 | 46,679 | 32,015 |
Q6 | 34,652 | 4.4 |
Q7 | 74,749 | 34,166 |
Q12 | 86,742 | 28,586 |
Q14 | 50,248 | 12,56 |
Q15 | 79,22 | 21,113 |
Q20 | 51,746 | 10,178 |
Q21 | 216,942 | 148,459 |