高同時実行オンライン トランザクション処理 (OLTP) と複雑なオンライン分析処理 (OLAP) の両方を処理する混合ワークロードシナリオでは、さまざまなタイプのクエリを適切なストレージエンジンに分散させることが、パフォーマンスを最適化するための鍵となります。PolarDB for X は、ルールベースの行および列ルーティング機能を提供します。この機能を使用すると、アカウント、SQL テンプレート、またはキーワードに基づいてルールを設定することで、クエリを行ストアノードまたは列ストア読み取り専用インスタンスに正確にルーティングできます。これにより、アプリケーションコードを変更することなく、トラフィックを迂回させ、クラスター全体のパフォーマンスを向上させることができます。
機能の概要
PolarDB for X は、次の 2 つの方法で列ストア読み取り専用インスタンスを使用してトラフィックを迂回させます。
列ストア読み取り専用インスタンスへの直接接続: アプリケーションは列ストア読み取り専用インスタンスのエンドポイントに直接接続し、分析クエリをそのインスタンスに明示的に送信します。この方法は直接的ですが、OLTP と OLAP のワークロードを手動で分類し、それに応じてアプリケーションコードを変更する必要があります。
プライマリインスタンスへの接続: アプリケーションはプライマリインスタンスのエンドポイントに接続します。その後、データベースオプティマイザーはコスト見積もりに基づいて、複雑なクエリを列ストア読み取り専用インスタンスに自動的にルーティングします。この方法はアプリケーションに対して透過的ですが、不正確なコスト見積もりにより誤ったルーティングが発生する可能性があります。
ルールベースの行および列ルーティング機能は、両方の方法の利点を兼ね備えています。ソースアカウント、特定のテンプレート、または SQL 文のキーワードに基づいて、プライマリインスタンスのエンドポイントで正確なルーティングポリシーを定義できます。このアプローチは、ルーティングの正確性を確保しながらアプリケーションコードの変更を回避するため、混合ワークロードシナリオでトラフィックを迂回させるための理想的な選択肢となります。
範囲
インスタンスの計算ノード (CN) バージョンは 5.4.20 以降である必要があります。
インスタンスバージョンの命名規則の詳細については、「リリースノート」をご参照ください。
インスタンスのバージョンを表示する方法の詳細については、「インスタンスのバージョンを表示および更新する」をご参照ください。
注意
パフォーマンスとリソース: 列ストアインデックスへのアクセスはリソースを大量に消費し、同時実行性が限られています。専用の列ストア読み取り専用インスタンス を追加して列ストアクエリを実行することで、プライマリインスタンスの OLTP ワークロードへの影響を回避できます。この機能は、低同時実行、ヘビースキャン、またはヘビー集約の OLAP クエリにのみ適しています。クエリ/秒 (QPS) が高いクエリを列ストア読み取り専用インスタンスにルーティングしないでください。
データ同期の遅延: 列ストアデータと行ストアデータの間の遅延は秒単位です。リアルタイムデータを必要とするアプリケーションのクエリを列ストア読み取り専用インスタンスにルーティングしないでください。
機能の制限: ルールベースのルーティングは
SELECTクエリに対してのみ機能します。トランザクション内のクエリは、ルールを使用して列ストア読み取り専用インスタンスにルーティングすることはできません。構文: ユーザー名やキーワードなど、ルーティングルールで定義されているすべてのフィールドでは、大文字と小文字は区別されません。
手順
ステップ 1: 環境を準備する
列ストア読み取り専用インスタンスを追加し、関連テーブルに列ストアインデックスを作成します。
プライマリインスタンスのエンドポイントを設定します。
説明この操作により、列ストア読み取り専用インスタンスがプライマリインスタンスのエンドポイントに関連付けられます。これにより、プライマリインスタンスのエンドポイントに送信されたクエリを列ストア読み取り専用インスタンスにルーティングできるようになります。
PolarDB for X コンソール に移動します。[インスタンスリスト] ページで、PolarDB-X 2.0 タブをクリックします。ターゲットのプライマリインスタンスの ID をクリックして、[基本情報] ページを開きます。
[接続情報] セクションで、[設定管理] をクリックします。

[設定管理] ダイアログボックスの [リソース設定] セクションで、ターゲットの列ストア読み取り専用インスタンスを [利用可能なインスタンス] リストから [選択されたインスタンス] リストに移動します。
ステップ 2: ルーティングルールを作成する
特権アカウントを使用してプライマリインスタンスに接続し、CREATE ROUTING_RULE コマンドを実行してルーティングルールを作成します。
CREATE ROUTING_RULE {IF NOT EXISTS} 'rule_name' TO 'user_name'
{FILTER BY TEMPLATE('template_id') | FILTER BY KEYWORD('kw1','kw2')}
WITH TYPE=[ROW | COLUMNAR];パラメーター
パラメーター | 説明 |
| ルール名。名前はグローバルに一意である必要があります。 |
| データベースアカウント名です。 |
| 任意。フィルター条件。これを使用して、テンプレートベースまたはキーワードベースのルーティングを指定します。このパラメーターを省略すると、ルールはアカウントベースのルーティングを適用します。
説明
|
| ルーティング先。
|
ルートの優先度
SQL 文が複数のルールに一致する場合、システムはこの優先順位に従います:
異なるルールタイプの場合、優先度はルールタイプによって決まります: テンプレートルーティング > キーワードルーティング > アカウントルーティング。
同じルールタイプの場合、優先度はアカウントのスコープによって決まります: 特定のアカウントのルール > すべてのアカウントのルール (
%)。同じルールタイプとアカウントスコープの場合、優先度はルーティングタイプによって決まります: 行ストア (
ROW) ルール > 列ストア (COLUMNAR) ルール。
例
列ストアインデックス
orders_col_indexを含むサンプルordersテーブルを作成します。CREATE TABLE `orders` ( `o_orderkey` int(11) NOT NULL, `o_custkey` int(11) NOT NULL, `o_orderstatus` varchar(1) NOT NULL, `o_totalprice` decimal(15, 2) NOT NULL, `o_orderdate` date NOT NULL, `o_orderpriority` varchar(15) NOT NULL, `o_clerk` varchar(15) NOT NULL, `o_shippriority` int(11) NOT NULL, `o_comment` varchar(79) NOT NULL, PRIMARY KEY (`o_orderkey`), CLUSTERED COLUMNAR INDEX `orders_col_index` (`o_orderdate`, `o_orderkey`) PARTITION BY HASH(`o_orderkey`) PARTITIONS 64 ) ENGINE = InnoDB DEFAULT CHARSET = latin1 PARTITION BY KEY(`o_orderkey`) PARTITIONS 16ルーティングルールを設定します。
アカウントルーティング
test0アカウントからのすべてのクエリをデフォルトで列ストアにルーティングします。CREATE ROUTING_RULE 'test0_col_rule' TO 'test0' WITH TYPE=COLUMNAR;結果をテストする
test0アカウントが任意のSELECTクエリを実行すると、EXPLAINを実行してクエリプランを表示できます。プランは、orders_col_indexなどの列ストアインデックスにアクセスすることを示しています。EXPLAIN SELECT COUNT(*) FROM orders;+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL EXECUTIONPLAN | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | HashAgg(COUNT(*)="SUM(COUNT(*))") | | Exchange(distribution=single, collation=[]) | | PartialHashAgg(COUNT(*)="COUNT()") | | OSSTableScan(tables="orders_col_index_$9554[p1,p2,p3,...p64]", shardCount=64, partition=[remote], sql="SELECT `o_orderkey` FROM `orders_col_index_$9554` AS `orders_col_index_$9554`") | | HitCache:false | | Source:PLAN_CACHE | | TemplateId: bc92bbe3 | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 7 rows in set (0.04 sec)別のアカウントが
SELECTクエリを実行した場合、列ストアインデックスにはアクセスしません。EXPLAIN SELECT COUNT(*) FROM orders;+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL EXECUTIONPLAN | +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | HashAgg(count(*)="SUM(count(*))") | | Gather(concurrent=true) | | LogicalView(tables="orders[p1,p2,p3,...p16]", shardCount=16, sql="SELECT COUNT(*) AS `count(*)` FROM `orders` AS `orders`", physicalPlan="[{table:orders,selectType:SIMPLE,type:index,key:PRIMARY,rows:1,filtered:100.0,extra:Scan rows(1, 1); Using index}]") | | HitCache:false | | Source:PLAN_CACHE | | TemplateId: b856efe3 | +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 6 rows in set (0.09 sec)
テンプレートルーティング
test0アカウントからの特定のタイプのクエリを強制的に行ストアにルーティングします。SQL テンプレート ID を取得します。
ターゲット SQL 文が
SELECT COUNT(*) FROM orders WHERE o_orderkey > ?;であると仮定します。EXPLAINコマンドを実行して、クエリプランのTemplateIdを表示できます。EXPLAIN SELECT COUNT(*) FROM orders WHERE o_orderkey > 10;出力は次のとおりです。
TemplateIdは24dd9ddeです。+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL EXECUTIONPLAN | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | HashAgg(COUNT(*)="SUM(COUNT(*))") | | Exchange(distribution=single, collation=[]) | | PartialHashAgg(COUNT(*)="COUNT()") | | OSSTableScan(tables="orders_col_index_$9554[p1,p2,p3,...p64]", shardCount=64, partition=[remote], sql="SELECT `o_orderkey` FROM `orders_col_index_$9554` AS `orders_col_index_$9554` WHERE (`o_orderkey` > ?)") | | HitCache:true | | Source:PLAN_CACHE | | TemplateId: 24dd9dde | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 7 rows in set (0.01 sec)テンプレートベースのルーティングルールを作成します。
CREATE ROUTING_RULE 'test0_row_rule' TO 'test0' FILTER BY TEMPLATE('24dd9dde') WITH TYPE=ROW;
結果をテストする
test0アカウントがこのテンプレートに一致するクエリ (例:... WHERE o_orderkey > 1000) を実行すると、クエリは行ストア (ordersテーブル) にルーティングされます。EXPLAIN SELECT COUNT(*) FROM orders WHERE o_orderkey > 1000;+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL EXECUTIONPLAN | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | HashAgg(COUNT(*)="SUM(COUNT(*))") | | Gather(concurrent=true) | | LogicalView(tables="orders[p1,p2,p3,...p16]", shardCount=16, sql="SELECT COUNT(*) AS `COUNT(*)` FROM `orders` AS `orders` WHERE (`o_orderkey` > ?)", physicalPlan="[{table:orders,selectType:SIMPLE,type:index,key:PRIMARY,rows:1,filtered:100.0,extra:Scan rows(1, 1); Using where; Using index}]") | | HitCache:true | | Source:PLAN_CACHE | | TemplateId: 24dd9dde | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 6 rows in set (0.01 sec)アカウントベースのルーティングを使用して、
test0アカウントからのすべてのクエリをデフォルトで列ストアインデックスにルーティングするように設定した場合、他のSELECTクエリは行ストアではなく列ストアインデックスにアクセスします。説明ルートの優先度 に従って、テンプレートルーティングはアカウントルーティングよりも優先されます。したがって、テンプレートに一致しないクエリは、アカウントルーティングルールに基づいて列ストアインデックスにアクセスします。
EXPLAIN SELECT COUNT(*) FROM orders;+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL EXECUTIONPLAN | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | HashAgg(COUNT(*)="SUM(COUNT(*))") | | Exchange(distribution=single, collation=[]) | | PartialHashAgg(COUNT(*)="COUNT()") | | OSSTableScan(tables="orders_col_index_$9554[p1,p2,p3,...p64]", shardCount=64, partition=[remote], sql="SELECT `o_orderkey` FROM `orders_col_index_$9554` AS `orders_col_index_$9554`") | | HitCache:true | | Source:PLAN_CACHE | | TemplateId: bc92bbe3 | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 7 rows in set (0.00 sec)
キーワードルーティング
特定のキーワードシーケンスを含むすべてのアカウントからのクエリを列ストアにルーティングします。
SQL 文のキーワードリストを取得します。
EXPLAIN KEYWORDを実行してクエリのキーワードを取得し、適切なリストを選択できます。EXPLAIN KEYWORD SELECT COUNT(1) AS cnt FROM orders WHERE o_clerk LIKE '%xx%'; +--------------------------------------------------------------------------------------------------+ | KEYWORDS_LIST | +--------------------------------------------------------------------------------------------------+ | 'select', 'count', '(', '1', ')', 'as', 'cnt', 'from', 'orders', 'where', 'o_clerk', 'like', '?' | +--------------------------------------------------------------------------------------------------+このタイプのクエリを一意に識別するキーワードのセットを選択し、ルールを作成します。
CREATE ROUTING_RULE 'keyword_columnar' TO '%' FILTER BY KEYWORD('select', 'count', 'as', 'cnt', 'from', 'orders', 'where', 'o_clerk', 'like') WITH TYPE="columnar";どのユーザーがこのキーワードシーケンスに一致するクエリを実行しても、それは列ストアインデックスにルーティングされます。
結果をテストする
一致する SQL 文に対して
EXPLAINを実行できます。クエリプランは、orders_col_indexなどの列ストアインデックスにアクセスすることを示しています。EXPLAIN SELECT COUNT(1) AS cnt FROM orders WHERE o_clerk LIKE '%xx%';+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | LOGICAL EXECUTIONPLAN | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | HashAgg(cnt="SUM(cnt)") | | Exchange(distribution=single, collation=[]) | | PartialHashAgg(cnt="COUNT()") | | OSSTableScan(tables="orders_col_index_$6ef7[p1,p2,p3,...p64]", shardCount=64, partition=[remote], sql="SELECT `o_orderkey` FROM `orders_col_index_$6ef7` AS `orders_col_index_$6ef7` WHERE (`o_clerk` LIKE ?)") | | HitCache:false | | Source:PLAN_CACHE | | TemplateId: e1b2617d | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 7 rows in set (0.03 sec)
ステップ 3: ルーティングルールを表示する
すべてのルールを表示する
SHOW ROUTING_RULES コマンドを使用するか、INFORMATION_SCHEMA.ROUTING_RULES ビューをクエリできます。
SHOW ROUTING_RULES [WHERE expr] [ORDER BY expr] [LIMIT expr]例
SHOW ROUTING_RULES ORDER BY HIT_COUNT DESC;
+------+------------------+-----------+-------------+--------------------------------------------------------------+--------------+---------------------+-----------+
| ID | RULE_NAME | USER_NAME | TEMPLATE_ID | KEYWORDS | ROUTING_TYPE | CREATE_TIME | HIT_COUNT |
+------+------------------+-----------+-------------+--------------------------------------------------------------+--------------+---------------------+-----------+
| 19 | keyword_columnar | % | NULL | [select, count, as, cnt, from, orders, where, o_clerk, like] | columnar | 2025-09-12 11:46:49 | 1 |
| 18 | test0_row_rule | test0 | 24dd9dde | [] | row | 2025-09-12 11:46:12 | 0 |
| 17 | test0_col_rule | test0 | NULL | [] | columnar | 2025-09-12 11:45:50 | 0 |
+------+------------------+-----------+-------------+--------------------------------------------------------------+--------------+---------------------+-----------+
3 rows in set (0.02 sec)
SHOW * FROM information_schema.routing_rules ORDER BY HIT_COUNT DESC;
+------+------------------+-----------+-------------+--------------------------------------------------------------+--------------+---------------------+-----------+
| ID | RULE_NAME | USER_NAME | TEMPLATE_ID | KEYWORDS | ROUTING_TYPE | CREATE_TIME | HIT_COUNT |
+------+------------------+-----------+-------------+--------------------------------------------------------------+--------------+---------------------+-----------+
| 19 | keyword_columnar | % | NULL | [select, count, as, cnt, from, orders, where, o_clerk, like] | columnar | 2025-09-12 11:46:49 | 1 |
| 18 | test0_row_rule | test0 | 24dd9dde | [] | row | 2025-09-12 11:46:12 | 0 |
| 17 | test0_col_rule | test0 | NULL | [] | columnar | 2025-09-12 11:45:50 | 0 |
+------+------------------+-----------+-------------+--------------------------------------------------------------+--------------+---------------------+-----------+
3 rows in set (0.01 sec)単一 SQL 文のルーティングプロセスを表示する
EXPLAIN ROUTING コマンドを使用して、特定の SQL 文の詳細なルーティング決定プロセスを表示できます。
EXPLAIN ROUTING <SQL>例
EXPLAIN ROUTING SELECT COUNT(*) FROM orders;+--------------+---------------------------+---------------+----------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ROUTING TYPE | CANDIDATE OPTIMIZER TYPES | WORKLOAD TYPE | OPTIMIZER TYPE | PLAN TYPE | DETAIL TRACE |
+--------------+---------------------------+---------------+----------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| COLUMNAR | NULL | AP | COLUMNAR | COLUMNAR |
determine routing type:
current user: test0
routing type: COLUMNAR, caused by determined by user:test0
cached plan from plan cache:
routing type: COLUMNAR, caused by plan cache
candidate optimizer types: {null}, caused by plan cache doesn't record
workload type: AP, caused by plan cache
optimizer type: COLUMNAR, caused by plan cache
plan type: COLUMNAR, caused by plan cache
plan type: COLUMNAR, caused by setting from planner context
|
+--------------+---------------------------+---------------+----------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)ルーティングタイプ (
ROUTING TYPE):COLUMNAR。候補オプティマイザータイプ (
CANDIDATE OPTIMIZER TYPES):NULL。ワークロードタイプ (
WORKLOAD TYPE):AP。オプティマイザータイプ (
OPTIMIZER TYPE):COLUMNAR。プランタイプ (
PLAN TYPE):COLUMNAR。詳細 (
DETAIL TRACE): このセクションでは、上記のタイプがどのように決定されるかを説明します。
ステップ 4: ルーティングルールを削除する
DROP ROUTING_RULE コマンドを使用して、1 つ以上のルールを削除できます。
DROP ROUTING_RULE {IF EXISTS} ruleName1{,...,ruleNameN};ルーティングルールを削除するには、特権アカウントを使用する必要があります。
例
DROP ROUTING_RULE test0_col_rule,test0_row_rule,keyword_columnar;