すべてのプロダクト
Search
ドキュメントセンター

PolarDB:ルールベースの行および列ルーティング

最終更新日:Nov 09, 2025

高同時実行オンライン トランザクション処理 (OLTP) と複雑なオンライン分析処理 (OLAP) の両方を処理する混合ワークロードシナリオでは、さまざまなタイプのクエリを適切なストレージエンジンに分散させることが、パフォーマンスを最適化するための鍵となります。PolarDB for X は、ルールベースの行および列ルーティング機能を提供します。この機能を使用すると、アカウント、SQL テンプレート、またはキーワードに基づいてルールを設定することで、クエリを行ストアノードまたは列ストア読み取り専用インスタンスに正確にルーティングできます。これにより、アプリケーションコードを変更することなく、トラフィックを迂回させ、クラスター全体のパフォーマンスを向上させることができます。

機能の概要

PolarDB for X は、次の 2 つの方法で列ストア読み取り専用インスタンスを使用してトラフィックを迂回させます。

  • 列ストア読み取り専用インスタンスへの直接接続: アプリケーションは列ストア読み取り専用インスタンスのエンドポイントに直接接続し、分析クエリをそのインスタンスに明示的に送信します。この方法は直接的ですが、OLTP と OLAP のワークロードを手動で分類し、それに応じてアプリケーションコードを変更する必要があります。

  • プライマリインスタンスへの接続: アプリケーションはプライマリインスタンスのエンドポイントに接続します。その後、データベースオプティマイザーはコスト見積もりに基づいて、複雑なクエリを列ストア読み取り専用インスタンスに自動的にルーティングします。この方法はアプリケーションに対して透過的ですが、不正確なコスト見積もりにより誤ったルーティングが発生する可能性があります。

ルールベースの行および列ルーティング機能は、両方の方法の利点を兼ね備えています。ソースアカウント、特定のテンプレート、または SQL 文のキーワードに基づいて、プライマリインスタンスのエンドポイントで正確なルーティングポリシーを定義できます。このアプローチは、ルーティングの正確性を確保しながらアプリケーションコードの変更を回避するため、混合ワークロードシナリオでトラフィックを迂回させるための理想的な選択肢となります。

範囲

インスタンスの計算ノード (CN) バージョンは 5.4.20 以降である必要があります。

説明

注意

  • パフォーマンスとリソース: 列ストアインデックスへのアクセスはリソースを大量に消費し、同時実行性が限られています。専用の列ストア読み取り専用インスタンス を追加して列ストアクエリを実行することで、プライマリインスタンスの OLTP ワークロードへの影響を回避できます。この機能は、低同時実行、ヘビースキャン、またはヘビー集約の OLAP クエリにのみ適しています。クエリ/秒 (QPS) が高いクエリを列ストア読み取り専用インスタンスにルーティングしないでください。

  • データ同期の遅延: 列ストアデータと行ストアデータの間の遅延は秒単位です。リアルタイムデータを必要とするアプリケーションのクエリを列ストア読み取り専用インスタンスにルーティングしないでください。

  • 機能の制限: ルールベースのルーティングは SELECT クエリに対してのみ機能します。トランザクション内のクエリは、ルールを使用して列ストア読み取り専用インスタンスにルーティングすることはできません。

  • 構文: ユーザー名やキーワードなど、ルーティングルールで定義されているすべてのフィールドでは、大文字と小文字は区別されません。

手順

ステップ 1: 環境を準備する

  1. 列ストア読み取り専用インスタンスを追加し、関連テーブルに列ストアインデックスを作成します。

  2. プライマリインスタンスのエンドポイントを設定します。

    説明

    この操作により、列ストア読み取り専用インスタンスがプライマリインスタンスのエンドポイントに関連付けられます。これにより、プライマリインスタンスのエンドポイントに送信されたクエリを列ストア読み取り専用インスタンスにルーティングできるようになります。

    1. PolarDB for X コンソール に移動します。[インスタンスリスト] ページで、PolarDB-X 2.0 タブをクリックします。ターゲットのプライマリインスタンスの ID をクリックして、[基本情報] ページを開きます。

    2. [接続情報] セクションで、[設定管理] をクリックします。image

    3. [設定管理] ダイアログボックスの [リソース設定] セクションで、ターゲットの列ストア読み取り専用インスタンスを [利用可能なインスタンス] リストから [選択されたインスタンス] リストに移動します。

ステップ 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];

パラメーター

パラメーター

説明

rule_name

ルール名。名前はグローバルに一意である必要があります。

user_name

データベースアカウント名です。% は、すべてのユーザーを表します。

FILTER BY

任意。フィルター条件。これを使用して、テンプレートベースまたはキーワードベースのルーティングを指定します。このパラメーターを省略すると、ルールはアカウントベースのルーティングを適用します。

  • TEMPLATE('template_id'): SQL テンプレート ID に基づいてクエリを照合します。これは、クエリ構造が固定されており、パラメーターのみが変更されるシナリオに適しています。

  • KEYWORD('kw1','kw2'): キーワードのシーケンスに基づいてクエリを照合します。クエリに指定されたすべてのキーワードが順番に含まれている場合、ルールにヒットします。これは、クエリ条件が固定されていないシナリオに適しています。

説明
  • 同じルーティングルールにテンプレートフィルターとキーワードフィルターの両方を設定することはできません。

  • キーワードフィルタリング:

    • キーワードは正規表現をサポートしていません。

    • 複数のキーワードを設定できますが、合計の長さは 500 文字を超えることはできません。

TYPE

ルーティング先。

  • ROW: クエリを行ストアノードにルーティングします。

  • COLUMNAR: クエリを列ストア読み取り専用インスタンスにルーティングします。

ルートの優先度

SQL 文が複数のルールに一致する場合、システムはこの優先順位に従います:

  1. 異なるルールタイプの場合、優先度はルールタイプによって決まります: テンプレートルーティング > キーワードルーティング > アカウントルーティング。

  2. 同じルールタイプの場合、優先度はアカウントのスコープによって決まります: 特定のアカウントのルール > すべてのアカウントのルール (%)。

  3. 同じルールタイプとアカウントスコープの場合、優先度はルーティングタイプによって決まります: 行ストア (ROW) ルール > 列ストア (COLUMNAR) ルール。

  1. 列ストアインデックス 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
  2. ルーティングルールを設定します。

    アカウントルーティング

    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 アカウントからの特定のタイプのクエリを強制的に行ストアにルーティングします。

    1. SQL テンプレート ID を取得します。

      ターゲット SQL 文が SELECT COUNT(*) FROM orders WHERE o_orderkey > ?; であると仮定します。EXPLAIN コマンドを実行して、クエリプランの TemplateId を表示できます。

      EXPLAIN SELECT COUNT(*) FROM orders WHERE o_orderkey > 10;

      出力は次のとおりです。TemplateId24dd9dde です。

      +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
      | 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)
    2. テンプレートベースのルーティングルールを作成します。

      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)

    キーワードルーティング

    特定のキーワードシーケンスを含むすべてのアカウントからのクエリを列ストアにルーティングします。

    1. 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', '?' |
      +--------------------------------------------------------------------------------------------------+
    2. このタイプのクエリを一意に識別するキーワードのセットを選択し、ルールを作成します。

      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;

よくある質問

SQL 文が複数のルーティングルールに一致する場合、どのルールが適用されますか?

PolarDB の分散バージョンは、次の優先順位でルールを適用します:

  1. 異なるルールタイプの場合、優先度はルールタイプによって決まります: テンプレートルーティング > キーワードルーティング > アカウントルーティング。

  2. 同じルールタイプの場合、優先度はアカウントのスコープによって決まります: 特定のアカウントのルール > すべてのアカウントのルール (%)。

  3. 同じルールタイプとアカウントスコープの場合、優先度はルーティングタイプによって決まります: 行ストア (ROW) ルール > 列ストア (COLUMNAR) ルール。

システムは、実行する優先度が最も高いルールを選択します。

SQL 文のテンプレート ID またはキーワードを取得するにはどうすればよいですか?

  • テンプレート ID の取得: ターゲット SQL 文の前に EXPLAIN キーワードを追加して実行します。次に、返された結果の TemplateId フィールドの値を見つけます。

  • キーワードの取得: ターゲット SQL 文の前に EXPLAIN KEYWORD キーワードを追加して実行します。返された結果の KEYWORDS_LIST から、このタイプのクエリを一意に識別するキーワードのシーケンスを選択できます。

関連トピック