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

PolarDB:オペレーター

最終更新日:Sep 22, 2026

このトピックでは、実行計画における一般的なオペレーターと、各オペレーターの役割について説明します。

オペレーターリファレンス

カテゴリ オペレーター
データノードへのプッシュダウン LogicalView、LogicalModifyView、PhyTableOperation、IndexScan
Join BKAJoin、NLJoin、HashJoin、SortMergeJoin、HashSemiJoin、SortMergeSemiJoin、MaterializedSemiJoin
ソート MemSort、TopN、MergeSort
集約 (GROUP BY) HashAgg、SortAgg
データの再配布または収集 交換、収集
フィルター Filter
プロジェクト Project
結果セットのマージ UnionAll、UnionDistinct
出力行の制限 (Limit/Offset...Fetch) Limit
ウィンドウ関数 OverWindow

データノードにプッシュダウンされるオペレーター

LogicalView

LogicalView は、ストレージレイヤーの MySQL データソースからデータを読み取ります。これは、他のデータベースの TableScan や IndexScan に似ていますが、より広範なプッシュダウン操作をサポートしています。LogicalView には、プッシュダウンされた SQL ステートメントとデータソース情報が含まれており、よりビューのように動作します。プッシュダウンされた SQL には、Project、Filter、集約、ソート、Join、サブクエリ操作が含まれる場合があります。次の例は、LogicalView の出力を示し、各フィールドについて説明します。

explain select * From sbtest1 where id > 1000;

出力:

Gather(concurrent=true)
   LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)")
LogicalView は 3 つの部分で構成されます。
  • tables:ストレージレイヤーの MySQL におけるテーブル名で、ピリオド.で区切られます。ピリオド.の前はデータベースシャード番号、後はシャード番号を含むテーブル名です。例えば、[000-127] はシャード番号が 000 から 127 までのすべてのテーブルを表します。
  • shardCount:アクセスするテーブルシャードの総数です。この例では、000 から 127 までの 128 個のテーブルシャードにアクセスします。
  • sql:ストレージレイヤーの MySQL に送信される SQL テンプレートです。PolarDB-X のランタイムでは、テーブル名は物理テーブル名に置き換えられ、パラメーター化された定数プレースホルダー?は実際のパラメーター値に置き換えられます。詳細については、「実行計画管理」をご参照ください。

LogicalModifyView

LogicalModifyView は、基盤となるデータソースのデータを変更します。また、INSERT、UPDATE、または DELETE のいずれかである SQL ステートメントも記録します。次の例は、LogicalModifyView の出力を示し、各フィールドについて説明します。
  • 例 1
    explain update sbtest1 set c='Hello, DRDS' where id > 1000;

    出力:

    LogicalModifyView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="UPDATE `sbtest1` SET `c` = ? WHERE (`id` > ?)"
  • 例 2
    explain delete from sbtest1 where id > 1000;

    出力:

    LogicalModifyView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="DELETE FROM `sbtest1` WHERE (`id` > ?)")
LogicalModifyView クエリプランのフィールドは LogicalView のフィールドと似ており、物理テーブルシャード、shardCount、SQL テンプレートが含まれます。同様に、実行計画キャッシュが有効になっているため、SQL はパラメーター化され、SQL テンプレート内の定数は?に置き換えられます。

PhyTableOperation

PhyTableOperation は、単一の物理テーブルシャードに対して直接操作を実行します。

説明 通常、このオペレーターは INSERT ステートメントでのみ使用されます。ただし、クエリが単一のシャードにルーティングされる場合、このオペレーターは SELECT ステートメントにも表示されることがあります。
explain insert into sbtest1 values(1, 1, '1', '1'),(2, 2, '2', '2');

出力:

PhyTableOperation(tables="SYSBENCH_CORONADB_1526954857179TGMMSYSBENCH_CORONADB_VGOC_0000_RDS.[sbtest1_001]", sql="INSERT INTO ? (`id`, `k`, `c`, `pad`) VALUES(?, ?, ?, ?)", params="`sbtest1_001`,1,1,1,1")
PhyTableOperation(tables="SYSBENCH_CORONADB_1526954857179TGMMSYSBENCH_CORONADB_VGOC_0000_RDS.[sbtest1_002]", sql="INSERT INTO ? (`id`, `k`, `c`, `pad`) VALUES(?, ?, ?, ?)", params="`sbtest1_002`,2,2,2,2")
この例では、INSERT ステートメントは 2 つの行を挿入し、各行は 1 つの PhyTableOperation オペレーターに対応します。PhyTableOperation は 3 つの部分で構成されます。
  • tables:物理テーブル名です。各 PhyTableOperation は、正確に 1 つの物理テーブルを対象とします。
  • sql:SQL テンプレートです。このテンプレートでは、テーブル名と定数がパラメーター化され、?に置き換えられます。対応するパラメーター値は、後続の params フィールドで提供されます。
  • params:テーブル名と定数を含む、SQL テンプレートのパラメーター値です。

IndexScan

IndexScan は、LogicalView と同様に、インデックステーブルをスキャンしてストレージレイヤーの MySQL データソースからデータを読み取ります。次の例は、IndexScan の出力を示し、各フィールドについて説明します。

explain select * from sequence_one_base where integer_test=1;

出力:

+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| IndexScan(tables="DRDS_POLARX1_QATEST_APP_000000_GROUP.gsi_sequence_one_index_3a0A_01", sql="SELECT `pk`, `integer_test`, `varchar_test`, `char_test`, `blob_test`, `tinyint_test`, `tinyint_1bit_test`, `smallint_test`, `mediumint_test`, `bit_test`, `bigint_test`, `float_test`, `double_test`, `decimal_test`, `date_test`, `time_test`, `datetime_test`, `timestamp_test`, `year_test`, `mediumtext_test` FROM `gsi_dml_sequence_one_index_index1` AS `gsi_dml_sequence_one_index_index1` WHERE (`integer_test` = ?)") |
上記の SQL ステートメントは、通常、sequence_one_base テーブルをスキャンします。integer_test はパーティションキーではないため、sequence_one_base のすべてのシャードをスキャンする必要があります。しかし、sequence_one_base テーブルには integer_test 列に gsi_sequence_one_index という名前のグローバルセカンダリインデックス (GSI) があるため、述語 integer_test=1 を使用してインデックステーブルをプルーニングします。その結果、IndexScan オペレーターが生成され、gsi_sequence_one_index テーブルの 1 つのシャードのみをスキャンします。

計算ノードまたはデータノードで実行されるオペレーター

UnionAll と UnionDistinct

UnionAll は UNION ALL に対応し、UnionDistinct は UNION DISTINCT に対応します。このオペレーターは通常、2 つ以上の入力を持ち、複数の入力からのデータを 1 つにマージします。例:

explain select * From sbtest1 where id > 1000 union distinct select * From sbtest1 where id < 200;

出力:

UnionDistinct(concurrent=true)
  Gather(concurrent=true)
    LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)")
  Gather(concurrent=true)
    LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` < ?)")

Gather

Gather は、複数のデータストリームを単一のデータストリームにマージします。上記の例では、Gather は各テーブルシャードから収集されたデータを 1 つの結果セットにマージします。Gather は通常、LogicalView の上に表示され、スキャンされたすべてのシャードからデータを収集します。

Exchange

Exchange は、データに対して計算を実行しない論理演算子です。入力データを再配布し、後続のオペレーターに渡します。一般的な再配布戦略には、以下が含まれます。
  • SINGLETON:複数の上流データストリームを 1 つの出力ストリームにマージします。この戦略は Gather と同等です。
  • HASH_DISTRIBUTED:特定の列によって上流の入力データを再パーティション化します。この戦略は、Join および Agg オペレーターを含む実行計画で一般的に使用されます。
  • BROADCAST_DISTRIBUTED:上流データの単一のコピーを複数の後続ノードに配布します。この戦略は、主に MPP 実行計画で使用されます。

MergeSort

MergeSort は、複数のソート済みデータストリームを単一のソート済みデータストリームにマージするマージソートオペレーターです。例:

explain select * from sbtest1 where id > 1000 order by id limit 5,10; 

出力:

MergeSort(sort="id ASC", offset=?1, fetch=?2)   
   LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?) ORDER BY `id` LIMIT (? + ?)")
MergeSort は 3 つの部分で構成されます。
  • sort:ソートフィールドとソート順です。id ASC は id フィールドによる昇順を意味します。DESC は降順を意味します。
  • offset:結果セットを取得する際にスキップする行数です。この例では値はパラメーター化されており、実際の値は 5 です。
  • fetch:返す行の最大数です。offset と同様に、値はパラメーター化されており、実際の値は 10 です。

Project

Project は射影操作を実行します。これは、入力データから特定の列を選択して出力するか、出力前に関数や式を通じて特定の列を変換します。定数を含めることもできます。

explain select '你好, DRDS', 1 / 2, CURTIME(); 

出力:

Project(你好, DRDS="_UTF-16'你好, DRDS'", 1 / 2="1 / 2", CURTIME()="CURTIME()")

フィルター

フィルターは、入力データにフィルター条件を適用します。条件を満たす行は通過し、それ以外の行は破棄されます。以下に、前述のオペレーターのほとんどを含む複雑な例を示します。

explain select k, avg(id) avg_id from sbtest1 where id > 1000 group by k having avg_id > 1300;

出力:

Filter(condition="avg_id > ?1")
  Project(k="k", avg_id="sum_pushed_sum / sum_pushed_count")
    SortAgg(group="k", sum_pushed_sum="SUM(pushed_sum)", sum_pushed_count="SUM(pushed_count)")
      MergeSort(sort="k ASC")
        LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT `k`, SUM(`id`) AS `pushed_sum`, COUNT(`id`) AS `pushed_count` FROM `sbtest1` WHERE (`id` > ?) GROUP BY `k` ORDER BY `k`")
WHERE id>1000WHERE (id > ?)