SelectDB支援行列混存模式,在列式儲存的基礎上額外儲存行格式資料,有效解決高並發點查情境下的I/O放大問題,顯著提升點查效能。
行列混存介紹
SelectDB預設採用列式儲存,列存在大規模分析查詢(如彙總、過濾)情境下具有明顯優勢。但在高並發點查情境(即按主鍵精確查詢少量行),列存需要逐列讀取資料並進行Merge,會引發大量隨機I/O,導致效能下降。
行列混存通過在列存資料之外,額外維護一份行格式的資料副本,使得點查時可以直接從行存中讀取完整的行資料,避免多列的隨機I/O,從而大幅提升高並發點查的效能。
行列混存適用於以下情境:
基於主鍵的高並發點查(如訂單詳情查詢、使用者資訊查詢)
需要返回行內全部或大部分列的
SELECT *查詢
啟用行列混存後,儲存空間會增加約2到4倍(具體取決於列數和資料特徵)。建議僅在有高並發點查需求的表上啟用該功能,以平衡效能與儲存成本。
使用文法
在CREATE TABLE語句的PROPERTIES中配置以下參數來啟用行列混存:
參數 | 說明 | 預設值 |
| 是否開啟行存。設定為 |
|
| 指定需要儲存行格式的列名列表(英文逗號分隔)。當 | 空(不指定則儲存所有列) |
| 行存資料頁(Page)的大小(位元組)。Page是儲存讀寫的最小單元,讀取一行至少產生一個Page的I/O。值越小點查效能越好但儲存空間越大,值越大儲存空間越小但點查I/O開銷越大。如果更偏向點查效能可配置較小值(如4096即4 KB),如果更偏向節省儲存空間可配置較大值(如65536即64 KB)。 |
|
行存命中條件
啟用行列混存後,行存命中分為以下兩種情況:
主鍵高並發點查
需要同時滿足以下條件:
表為Unique Key模型(MOW表),即建表時設定了
enable_unique_key_merge_on_write = true。已開啟行存(
store_row_column = true或設定了row_store_columns)。查詢的WHERE條件包含所有主鍵列的等值條件,且條件之間用AND串連。例如
SELECT * FROM tbl WHERE k1 = 1 AND k2 = 2。
如果行存只包含部分列(通過row_store_columns指定),但查詢的列不在行存中,則這些列會從列存中查詢。通過EXPLAIN查看是否包含SHORT-CIRCUIT標記來確認是否命中主鍵高並發點查最佳化。更多詳情請參考高並發點查。
一般的SELECT *查詢
需要同時滿足以下條件:
表模型為Duplicate Key或Unique Key(MOW表)。
已開啟全列行存(
store_row_column = true)。查詢必須是
SELECT *,且需要命中TOPN的延遲物化最佳化(查詢包含ORDER BY和LIMIT子句)。
樣本:
SELECT * FROM tbl WHERE k < 10 ORDER BY k LIMIT 10;通過EXPLAIN查看是否包含FETCH ROW STORE和OPT TWO PHASE標記來確認是否命中行存。
對於分析型查詢(如彙總、範圍掃描),系統仍會使用列存路徑,以保證最佳的分析效能。
使用樣本
行存配置在建表時指定,建表後不支援修改。
開啟全列行存
對錶的所有列開啟行存,適合SELECT *類高並發點查情境:
CREATE TABLE user_profile (
user_id BIGINT,
user_name VARCHAR(64),
age INT,
city VARCHAR(32),
register_date DATE
)
UNIQUE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 16
PROPERTIES (
"store_row_column" = "true",
"enable_unique_key_merge_on_write" = "true"
);開啟部分列行存
僅對查詢中常用的部分列開啟行存,可以在節省儲存空間的同時提升點查效能:
CREATE TABLE order_info (
order_id BIGINT,
user_id BIGINT,
amount DECIMAL(12, 2),
status INT,
create_time DATETIME,
detail VARCHAR(1024)
)
UNIQUE KEY(order_id)
DISTRIBUTED BY HASH(order_id) BUCKETS 32
PROPERTIES (
"row_store_columns" = "user_id,amount,status,create_time",
"enable_unique_key_merge_on_write" = "true"
);調整行存Page大小
對於行寬較大(列多或欄位較長)的表,可適當增大row_store_page_size以減少Page數量,提升讀取效率:
CREATE TABLE wide_table (
id BIGINT,
col1 VARCHAR(256),
col2 VARCHAR(256),
col3 VARCHAR(256)
)
UNIQUE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 8
PROPERTIES (
"store_row_column" = "true",
"row_store_page_size" = "65536",
"enable_unique_key_merge_on_write" = "true"
);注意事項
開啟行存後儲存空間會增加,典型情境下約為原始表的2到4倍,具體空間佔用需使用實際資料測試。
row_store_page_size對儲存空間也有影響,建議根據業務情境在點查效能和儲存空間之間權衡。如果僅部分列需要行存,建議使用
row_store_columns指定具體列,可有效減少額外儲存開銷。行存配置在建表時指定,建表後不支援修改。