ApsaraDB for SelectDB はデフォルトで列のストアを採用しています。ワイドテーブルでは、単一の行を取得する際に列ごとのランダム読み取り I/O が発生し、ポイントクエリの応答が遅くなります。また、フロントエンド(FE)は Java で実装されているため、多数の同時実行 SQL クエリを解析すると、高い CPU オーバーヘッドが発生します。これらの課題に対処するため、SelectDB では、ローストア、ショートクエリパス、およびプリペアドステートメントという 3 つの補完的なメカニズムを提供しており、高並列ポイントクエリのレイテンシを大幅に低減します。
仕組み
| メカニズム | 機能概要 |
|---|---|
| 行ストア | 各行のコピーを行形式で保存し、ポイントクエリにおける列ごとの I/O を排除します |
| ショートクエリパス | クエリ オプテマイザーが標準の実行エンジンをバイパスし、プライマリキー検索を単一のリモートプロシージャコール(RPC)で解決できるようにします |
| プリペアドステートメント | FE 内でセッションレベルに SQL ステートメントおよび式の解析結果をキャッシュし、高並列ワークロードにおける繰り返し解析のオーバーヘッドを削減します |
ローストアの利用タイミング
ローストアは追加のストレージ容量を消費します。以下の表を参考に、有効化の可否を判断してください。
| シナリオ | 推奨ストレージ | 推奨設定 |
|---|---|---|
| 高並列プライマリキー検索 | ローストア | ローストアと書き込み時マージ(MoW)を有効化 |
| ワイドテーブルにおける複雑な集約およびマルチテーブル JOIN | 列のストア | デフォルトの列のストアを維持 |
| 混合ワークロード(ポイントクエリ+分析処理) | 両方 | ローストアを必要に応じて選択的に有効化 |
ローストアの有効化
ローストアは、テーブル作成時にのみ有効化できます。CREATE TABLE ステートメントに以下のプロパティを追加します:
"store_row_column" = "true"テーブル作成後にローストアを有効化または無効化することはできません。
Unique Key モデルにおけるポイントクエリの最適化
Unique Key モデルのテーブルにおいて、enable_unique_key_merge_on_write および store_row_column の両方を true に設定すると、クエリ オプテマイザーはプライマリキーによるポイントクエリに対してショートクエリパスを起動します。このようなクエリの実行には、1 回の RPC だけで済みます。
以下は、ローストアおよび MoW を有効化したテーブルを作成する例です:
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"
);| プロパティ | 値 | 目的 |
|---|---|---|
enable_unique_key_merge_on_write | true | 書き込み時マージ(MoW)を有効化し、ストレージエンジンがプライマリキーで行を高速に特定できるようにします |
store_row_column | true | 高速な全行取得のためにローストアを有効化します |
light_schema_change | true | ショートクエリパスの動作に必須です。オプテマイザーは、軽量スキーマ変更から取得したユニークな列 ID を使用して列を特定します |
短いクエリパスは、WHERE 句が単一テーブルのキー列に対する等価条件を含む場合にのみ適用されます。たとえば:
SELECT * FROM tbl_point_query WHERE key = 123;プリペアドステートメントの利用
プリペアドステートメントは MySQL プロトコルと完全互換です。FE で有効化すると、SelectDB は各 SQL ステートメントおよびその式を 1 度だけ解析し、その結果をセッションレベルのメモリにキャッシュします。その後の実行ではキャッシュされたオブジェクトを再利用し、解析処理を完全に省略できます。CPU バウンドなプライマリキーによるポイントクエリでは、スループットを 4 倍以上向上させることができます。
プリペアドステートメントは、プライマリキーに基づくポイントクエリでのみ機能します。
Java Database Connectivity(JDBC)を介してプリペアドステートメントを有効化する方法:
JDBC URL に
useServerPrepStmts=trueを追加します:jdbc:mysql://127.0.0.1:9030/ycsb?useServerPrepStmts=trueステートメントを 1 度だけ準備し、複数のクエリ間で
PreparedStatementオブジェクトを再利用します:// ? をプレースホルダーとして使用。readStatement を複数のクエリで再利用します。 PreparedStatement readStatement = conn.prepareStatement( "SELECT * FROM tbl_point_query WHERE key = ?" ); readStatement.setInt(1, 1234); ResultSet resultSet = readStatement.executeQuery(); // 次のクエリでも同じステートメントを再利用 readStatement.setInt(1, 1235); resultSet = readStatement.executeQuery();
行キャッシュの有効化
SelectDB には、データを列ごとに格納するページキャッシュが備わっています。各ページには 1 列分のデータが格納されます。ローストアモードでは、1 つのページに複数列のデータが格納されるため、大規模な分析クエリによってキャッシュから追い出されやすくなり、ヒット率が低下します。
行キャッシュは、この課題に対処するために専用の行レベルキャッシュを維持し、最近使用されていない順(LRU)の立ち退きポリシーを採用します。これにより、大規模な分析クエリがキャッシュ領域を競合しても、頻繁にアクセスされる行をメモリ上に保持できます。
バックエンド(BE)の設定で行キャッシュを構成します:
| パラメーター | デフォルト値 | 説明 |
|---|---|---|
disable_storage_row_cache | false | 行キャッシュの可用性を制御します。デフォルトは false(有効)であり、行キャッシュを有効化したままになります。true に設定すると行キャッシュが無効化され、メモリオーバーヘッドを削減できます。 |
row_cache_mem_limit | 20 | 行キャッシュに割り当てるメモリの最大割合です。デフォルトは 20 % です。 |
制限事項
ローストアは、テーブル作成時のみ有効化可能です。既存テーブルの変更はサポートされていません。
ショートクエリパスは、単一テーブルのキー列に対する等価条件(
=)にのみ適用されます。JOIN クエリおよびネストされたサブクエリはサポートされていません。WHERE句は、キー列のみを参照する必要があります(キーと値のペアによるクエリ)。プリペアドステートメントは、プライマリキーによるポイントクエリでのみ機能します。
ショートクエリパスが正しく機能するには、
light_schema_change = trueの設定が必要です。