Topik ini menjelaskan cara menginterpretasikan Query Profile untuk mengidentifikasi bottleneck kinerja pada instans StarRocks Anda serta menyediakan teknik optimasi guna meningkatkan efisiensi kueri.
Ikhtisar Query Profile
Visualisasikan Query Profile
Anda dapat menggunakan StarRocks Manager untuk menganalisis Query Profile secara visual. Untuk informasi selengkapnya, lihat Pengenalan Query Profile.
Identifikasi bottleneck kueri
Semakin lama waktu yang dikonsumsi oleh suatu operator, semakin gelap warnanya. Tiga operator teratas berdasarkan waktu eksekusi disorot untuk memudahkan identifikasi bottleneck kueri.
Studi kasus optimasi
Bitmap index
Bitmap index adalah jenis khusus indeks database yang menggunakan array bit. Setiap bit dalam array tersebut berkorespondensi dengan satu baris dalam tabel data, dengan nilai bit (0 atau 1) ditentukan oleh nilai baris yang bersangkutan.
-
Gunakan Bitmap index untuk meningkatkan kinerja kueri pada kolom dengan kardinalitas rendah dan banyak nilai berulang, seperti kolom
gender. -
Untuk memeriksa apakah suatu kueri menggunakan Bitmap index, lihat bidang
BitmapIndexFilterRowsdalam Query Profile.
Buat indeks
-
Buat Bitmap index saat membuat tabel.
CREATE TABLE `student_info` ( `s_stukey` bigint(20) NULL COMMENT "", `s_name` varchar(65533) NULL COMMENT "", `s_gender` varchar(65533) NULL COMMENT "", INDEX index1 (s_gender) USING BITMAP COMMENT 'index1' ) ENGINE=OLAP DUPLICATE KEY(`s_stukey`) COMMENT "OLAP" DISTRIBUTED BY HASH(`s_stukey`); INSERT INTO student_info VALUES (001,'student#000000019','male'), (002,'student#000000020','male'), (003,'student#000000021','male'), (004,'student#000000022','female'); -
Buat Bitmap index pada tabel yang sudah ada dengan menggunakan
CREATE INDEX.CREATE INDEX index_name ON table_name (column_name) [USING BITMAP] [COMMENT ''];
Periksa progres pembuatan indeks
SHOW ALTER TABLE COLUMN [FROM db_name];
Lihat indeks
SHOW {INDEX[ES] | KEY[S] } FROM [db_name.]table_name [FROM db_name];
MySQL [db_test]> show index from student_info;
+------------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+------------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| db_test.student_info | | index1 | | s_gender | | | | | | BITMAP | index1 |
+------------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
1 row in set (0.01 sec)
Hapus indeks
DROP INDEX index_name ON [db_name.]table_name;
Uji kueri satu kolom
-
Jalankan kueri yang memfilter kolom
s_gender.select * from student_info where s_gender='male'; -
Lihat Profil.
Klik OLAP_SCAN, lalu klik tab Node Details di sebelah kanan. Filter metrik untuk
Bitmapguna memastikan bahwa Bitmap index telah diterapkan.
Bloom filter index
Bloom filter index dengan cepat menentukan apakah suatu file data berisi data target. Jika tidak, file tersebut dilewati sehingga mengurangi jumlah data yang dipindai. Bloom filter hemat ruang dan cocok untuk kolom dengan kardinalitas tinggi, seperti kolom ID.
-
Pada model Primary Key dan Duplicate, Anda dapat membuat Bloom filter index pada kolom apa pun. Pada model Aggregate dan Update, Anda hanya dapat membuat Bloom filter index pada kolom kunci.
-
Bloom filter index tidak didukung untuk kolom dengan tipe data TINYINT, FLOAT, DOUBLE, atau DECIMAL.
-
Bloom filter index hanya meningkatkan kinerja untuk kueri yang mengandung predikat
inatau=, sepertiSELECT ... WHERE ... IN ()danSELECT ... WHERE column = .... -
Untuk memeriksa apakah suatu kueri menggunakan Bloom filter index, lihat bidang
BloomFilterFilterRowsdalam Query Profile.
Buat indeks
Saat membuat tabel, Anda dapat membuat Bloom filter index dengan menentukan bloom_filter_columns dalam klausa PROPERTIES. Contoh berikut menunjukkan cara melakukannya.
CREATE TABLE table1
(
k1 BIGINT,
k2 LARGEINT,
v1 VARCHAR(2048) REPLACE,
v2 SMALLINT DEFAULT "10"
)
ENGINE = olap
PRIMARY KEY(k1, k2)
DISTRIBUTED BY HASH (k1, k2) BUCKETS 10
PROPERTIES("bloom_filter_columns" = "k1,k2"); -- Pisahkan beberapa kolom indeks dengan koma (,).
Lihat indeks
SHOW CREATE TABLE table1;
Ubah indeks
Contohnya:
-
Tambahkan Bloom filter index untuk kolom
v1.ALTER TABLE table1 SET ("bloom_filter_columns" = "k1,k2,v1"); -
Hapus Bloom filter index untuk kolom
k2.ALTER TABLE table1 SET ("bloom_filter_columns" = "k1"); -
Hapus semua Bloom filter index dari
table1.ALTER TABLE table1 SET ("bloom_filter_columns" = "");
Contoh
-
Ambil tabel
customerdari TPC-H sebagai contoh. Tambahkan Bloom filter index pada kolom dengan kardinalitas tinggi yang bukan kunci pengurutan, seperti kolomc_phone.ALTER TABLE tpc_h_sf100.customer SET ("bloom_filter_columns" = "c_custkey, c_phone"); -
Lihat indeks untuk memastikan bahwa Bloom filter index telah ditambahkan.
SHOW CREATE TABLE tpc_h_sf100.customer;| customer | CREATE TABLE `customer` ( `c_custkey` bigint(20) NULL COMMENT "", `c_name` varchar(65533) NULL COMMENT "", `c_address` varchar(65533) NULL COMMENT "", `c_nationkey` bigint(20) NULL COMMENT "", `c_phone` varchar(65533) NULL COMMENT "", `c_acctbal` double NULL COMMENT "", `c_mktsegment` varchar(65533) NULL COMMENT "", `c_comment` varchar(65533) NULL COMMENT "", `Gender` varchar(65533) NULL DEFAULT "default_value" COMMENT "" ) ENGINE=OLAP DUPLICATE KEY(`c_custkey`) COMMENT "OLAP" DISTRIBUTED BY HASH(`c_custkey`) BUCKETS 24 PROPERTIES ( "replication_num" = "1", "bloom_filter_columns" = "c_custkey, c_phone", "in_memory" = "false", "storage_format" = "DEFAULT", "enable_persistent_index" = "false", "compression" = "LZ4" ); | -
Jalankan kueri yang memfilter kolom
c_phone.select * from tpc_h_sf100.customer where c_phone = "10-334-921-5346"; -
Lihat Profil.
Klik OLAP_SCAN, lalu klik tab Node Details di sebelah kanan. Temukan metrik
BloomFilterFilterRowsuntuk memastikan bahwa Bloom filter index aktif.
Optimalkan untuk kesenjangan data
Contoh ini menggunakan tabel lineitem dari TPC-H dan memilih kolom dengan distribusi tidak seragam sebagai kunci bucketing untuk menunjukkan masalah kesenjangan data. Dalam kasus ini, kolom l_tag memiliki distribusi nilai yang tidak seragam.
-
Buat data uji. Tambahkan kolom baru ke tabel
lineitemdari TPC-H untuk digunakan sebagai kunci distribusi.CREATE TABLE `lineitem_tag` ( `l_orderkey` bigint(20) NULL COMMENT "", `l_partkey` bigint(20) NULL COMMENT "", `l_suppkey` bigint(20) NULL COMMENT "", `l_linenumber` int(11) NULL COMMENT "", `l_quantity` double NULL COMMENT "", `l_extendedprice` double NULL COMMENT "", `l_discount` double NULL COMMENT "", `l_tax` double NULL COMMENT "", `l_returnflag` varchar(65533) NULL COMMENT "", `l_linestatus` varchar(65533) NULL COMMENT "", `l_shipdate` date NULL COMMENT "", `l_commitdate` date NULL COMMENT "", `l_receiptdate` date NULL COMMENT "", `l_shipinstruct` varchar(65533) NULL COMMENT "", `l_shipmode` varchar(65533) NULL COMMENT "", `l_comment` varchar(65533) NULL COMMENT "", `l_tag` varchar(65533) default 'false' COMMENT "" ) ENGINE=OLAP DUPLICATE KEY(`l_orderkey`) COMMENT "OLAP" DISTRIBUTED BY HASH(`l_tag`) BUCKETS 96 PROPERTIES ( "replication_num" = "1", "in_memory" = "false", "storage_format" = "DEFAULT", "enable_persistent_index" = "false" ); insert into lineitem_tag select *, 'false' as l_tag from tpc_h_sf100.lineitem; -
Jalankan kueri untuk melakukan pemindaian tabel penuh.
select count(1) from lineitem_tag; -
Lihat Profil.
Klik OLAP_SCAN dan buka tab Node di sebelah kanan. Bandingkan waktu SCAN di bawah MaxTime dan MinTime. Jika perbedaan waktunya mencapai beberapa orde besar, kemungkinan terjadi kesenjangan data.
-
Optimalkan struktur tabel dengan mendefinisikan ulang kunci distribusi. Buat tabel baru bernama
lineitem2dan ubah kunci bucketing daril_tagmenjadil_orderkeyuntuk mengatasi kesenjangan data. Pernyataan berikut membuat tabel, di mana perubahan krusialnya adalahDISTRIBUTED BY HASH(<code data-tag="code" id="code_77b94d1ef39c">l_orderkey) BUCKETS 96.CREATE TABLE `lineitem2` ( `l_orderkey` bigint(20) NULL COMMENT "", `l_partkey` bigint(20) NULL COMMENT "", `l_suppkey` bigint(20) NULL COMMENT "", `l_linenumber` int(11) NULL COMMENT "", `l_quantity` double NULL COMMENT "", `l_extendedprice` double NULL COMMENT "", `l_discount` double NULL COMMENT "", `l_tax` double NULL COMMENT "", `l_returnflag` varchar(65533) NULL COMMENT "", `l_linestatus` varchar(65533) NULL COMMENT "", `l_shipdate` date NULL COMMENT "", `l_commitdate` date NULL COMMENT "", `l_receiptdate` date NULL COMMENT "", `l_shipinstruct` varchar(65533) NULL COMMENT "", `l_shipmode` varchar(65533) NULL COMMENT "", `l_comment` varchar(65533) NULL COMMENT "", `l_tag` varchar(65533) NULL DEFAULT "default_value" COMMENT "" ) ENGINE=OLAP DUPLICATE KEY(`l_orderkey`) COMMENT "OLAP" DISTRIBUTED BY HASH(`l_orderkey`) BUCKETS 96 PROPERTIES ( "replication_num" = "1", "bloom_filter_columns" = "l_orderkey", "in_memory" = "false", "storage_format" = "DEFAULT", "enable_persistent_index" = "false", "compression" = "LZ4" ); -
Tinjau kembali Profil. Bandingkan waktu SCAN di bawah MaxTime dan MinTime. Anda dapat melihat bahwa masalah kesenjangan data telah dimitigasi.
Tampilan yang di-materialisasi satu tabel
Tampilan yang di-materialisasi satu tabel (juga dikenal sebagai Rollup) di StarRocks adalah jenis khusus indeks yang tidak dapat dikueri secara langsung. Jika gudang data Anda berisi banyak kueri kompleks atau berulang, Anda dapat membuat tampilan yang di-materialisasi satu tabel untuk mempercepatnya.
Uji kueri
-
Ambil tabel
lineitemdari TPC-H sebagai contoh dan jalankan kueri.select l_returnflag,l_linestatus,l_shipmode,sum(l_extendedprice) from lineitem group by l_returnflag,l_linestatus,l_shipmode; -
Kueri awal membutuhkan waktu 1115 ms untuk diselesaikan karena belum ada tampilan yang di-materialisasi.
-
Lihat Profil.
Klik OLAP_SCAN dan buka tab Node di sebelah kanan. Anda dapat melihat bahwa Rollup memindai tabel
lineitemitu sendiri.
Buat tampilan yang di-materialisasi
CREATE MATERIALIZED VIEW material_test AS select l_returnflag,l_linestatus ,l_shipmode,sum(l_extendedprice) from lineitem group by l_returnflag,l_linestatus,l_shipmode;
Memverifikasi hit tampilan yang di-materialisasi
-
Anda dapat menggunakan perintah EXPLAIN untuk memeriksa apakah kueri menggunakan tampilan yang di-materialisasi satu tabel.
explain select l_returnflag,l_linestatus ,l_shipmode,sum(l_extendedprice) from lineitem group by l_returnflag,l_linestatus,l_shipmode;Dalam hasil yang dikembalikan,
rollup: material_testmenunjukkan bahwa kueri menggunakan tampilan yang di-materialisasi bernamamaterial_test.0:OlapScanNode TABLE: lineitem PREAGGREGATION: OFF. Reason: null partitions=1/1 rollup: material_test tabletRatio=96/96 tabletList=15646,15648,15650,15652,15654,15656,15658,15660,15662,15664 ... cardinality=600037902 avgRowSize=14.285666 numNodes=0 -
Lihat Profil.
Klik OLAP_SCAN. Pada tab Node di sebelah kanan, Anda dapat melihat bahwa kueri menggunakan tampilan yang di-materialisasi dan waktu kueri berkurang menjadi 0,05 ms.
Verifikasi apakah JoinRuntimeFilter aktif
Ketika tabel kanan dalam operasi JOIN membangun tabel hash, Runtime Filter dibuat. Filter ini dikirim ke sisi kiri pohon kueri dan didorong ke operator scan bila memungkinkan. Anda dapat melihat metrik terkait JoinRuntimeFilter pada tab Node Details operator scan.
-
Ambil query72.sql dari TPC-DS sebagai contoh.
select i_item_desc, w_warehouse_name, d1.d_week_seq, sum(case when p_promo_sk is null then 1 else 0 end) no_promo, sum(case when p_promo_sk is not null then 1 else 0 end) promo, count(*) total_cnt from inventory join catalog_sales on (cs_item_sk = inv_item_sk) join warehouse on (w_warehouse_sk=inv_warehouse_sk) join item on (i_item_sk = cs_item_sk) join customer_demographics on (cs_bill_cdemo_sk = cd_demo_sk) join household_demographics on (cs_bill_hdemo_sk = hd_demo_sk) join date_dim d1 on (cs_sold_date_sk = d1.d_date_sk) join date_dim d2 on (inv_date_sk = d2.d_date_sk) join date_dim d3 on (cs_ship_date_sk = d3.d_date_sk) left outer join promotion on (cs_promo_sk=p_promo_sk) left outer join catalog_returns on (cr_item_sk = cs_item_sk and cr_order_number = cs_order_number) where d1.d_week_seq = d2.d_week_seq and inv_quantity_on_hand < cs_quantity and d3.d_date > (cast(d1.d_date AS DATE) + interval '5' day) and hd_buy_potential = '>10000' and d1.d_year = 1999 and cd_marital_status = 'D' group by i_item_desc,w_warehouse_name,d1.d_week_seq order by total_cnt desc, i_item_desc, w_warehouse_name, d1.d_week_seq limit 100; -
Lihat Profil.
Klik OLAP_SCAN, lalu klik tab Node Details di sebelah kanan. Anda dapat melihat bahwa JoinRuntimeFilter dipicu saat operator scan memindai tabel inventory.
Colocate Join
Di StarRocks, untuk menggunakan fitur Colocate Join, Anda harus menetapkan tabel ke Colocation Group (CG) saat membuatnya. Tabel-tabel dalam CG yang sama harus mengikuti Colocation Group Schema (CGS) yang sama, yang menjamin data mereka didistribusikan di node BE yang sama. Ketika kolom join juga merupakan kunci bucketing, node komputasi hanya perlu melakukan join lokal. Hal ini mengurangi waktu transfer data antar node dan meningkatkan kinerja kueri. Berbeda dengan Shuffle atau Broadcast Join, Colocate Join menghindari transfer data jaringan, yang secara signifikan meningkatkan kinerja kueri.
Buat tabel colocated
StarRocks hanya mendukung operasi Colocate Join pada tabel dalam database yang sama.
CREATE TABLE tbl (k1 int, v1 int sum)
DISTRIBUTED BY HASH(k1)
BUCKETS 8
PROPERTIES(
"colocate_with" = "group1"
);
Hapus Colocation Group
Ketika tabel terakhir dalam suatu Group dihapus secara permanen, Group tersebut juga otomatis dihapus. Penghapusan permanen berarti tabel dihapus dari Recycle Bin. Biasanya, setelah tabel dihapus menggunakan perintah DROP TABLE, tabel tersebut tetap berada di Recycle Bin selama satu hari secara default sebelum dihapus secara permanen.
Lihat informasi grup
Sebagai contoh, jalankan perintah berikut untuk melihat informasi grup.
SHOW PROC '/colocation_group';
Perintah tersebut mengembalikan informasi berikut.
+-------------+--------------+----------+------------+----------------+----------+----------+
| GroupId | GroupName | TableIds | BucketsNum | ReplicationNum | DistCols | IsStable |
+-------------+--------------+----------+------------+----------------+----------+----------+
| 11912.11916 | 11912_group1 | 11914 | 8 | 3 | int(11) | true |
+-------------+--------------+----------+------------+----------------+----------+----------+
Tabel berikut menjelaskan kolom-kolom tersebut.
|
Kolom |
Deskripsi |
|
GroupId |
Pengidentifikasi unik grup di seluruh kluster. Bagian pertama adalah ID database, dan bagian kedua adalah ID grup. |
|
GroupName |
Nama lengkap grup. |
|
TableIds |
Daftar ID tabel yang termasuk dalam grup ini. |
|
BucketsNum |
Jumlah bucket. |
|
ReplicationNum |
Jumlah replika. |
|
DistCols |
Tipe data kolom distribusi. |
|
IsStable |
Menunjukkan apakah grup tersebut stabil. |
Anda dapat menjalankan perintah berikut untuk melihat distribusi data grup tertentu.
SHOW PROC '/colocation_group/GroupId';
SHOW PROC '/colocation_group/11912.11916';
Perintah tersebut mengembalikan informasi berikut.
+-------------+---------------------+
| BucketIndex | BackendIds |
+-------------+---------------------+
| 0 | 10002, 10004, 10003 |
| 1 | 10002, 10004, 10003 |
| 2 | 10002, 10004, 10003 |
| 3 | 10002, 10004, 10003 |
| 4 | 10002, 10004, 10003 |
| 5 | 10002, 10004, 10003 |
| 6 | 10002, 10004, 10003 |
| 7 | 10002, 10004, 10003 |
+-------------+---------------------+
8 rows in set (0.00 sec)
Ubah properti grup
ALTER TABLE tbl SET ("colocate_with" = "group_name");
-
Menggunakan data TPC-H sebagai contoh, lakukan operasi berikut.
use tpc_h_sf100; ALTER TABLE orders SET ("colocate_with" = "cg_tpc_orders"); ALTER TABLE lineitem SET ("colocate_with" = "cg_tpc_orders"); -
Jalankan kueri berikut.
select count(1) from orders as o join lineitem as l on o.o_orderkey = l.l_orderkey; -
Anda dapat memeriksa apakah Colocate Join aktif pada tab Query Plan untuk kueri di UI StarRocks Manager.
Jika nilai
colocateadalah true, berarti Colocate Join telah diterapkan. Hal ini ditunjukkan olehcolocate: truedalam rencana eksekusi. Fragmen rencana eksekusi yang sesuai adalah:2:HASH JOIN | join op: INNER JOIN (COLOCATE) | colocate: true | equal join conjunct: 10: l_orderkey = 1: o_orderkey | |----1:OlapScanNode | TABLE: orders | PREAGGREGATION: ON | PREDICATES: 1: o_orderkey IS NOT NULL | partitions=1/1 | rollup: orders | tabletRatio=96/96 | tabletList=12403,12405,12407,12409,12411,12413,12415,12417,12419,12421 ... | cardinality=135000000 | avgRowSize=1.0 | numNodes=0
Verifikasi pemangkasan bucket dan partisi
Pada tab Query Plan untuk kueri Anda di UI StarRocks Manager, Anda dapat melihat parameter partition dan tabletRatio untuk memverifikasi apakah pemangkasan partisi atau pemangkasan bucket aktif.