この記事は、Huawei Cloud Community「GaussDB (DWS) Vectorized Execution Engine 詳細な説明」(著者: yd_212508532) から共有されたものです。
序文
- 対象バージョン:[ベースライン機能]
従来のほとんどの行実行エンジンは、一度に 1 タプルの実行モードを採用しています。このように、実行プロセス中のほとんどの時間、CPU はデータの処理には使用されず、実行ツリーの走査に使用されます。 CPU の有効利用率が低くなります。 OLAP シナリオで膨大な数の関数呼び出しが発生すると、膨大なオーバーヘッドが必要になります。この問題を解決するために、GaussDB (DWS) にベクトル化エンジンが追加されました。ベクトル化エンジンはタプルの一括実行モードを使用します。これにより、実行ノードを走査するコストを大幅に削減できます。同時に、ベクトル化エンジンは列ストレージにも自然に接続され、基礎となるスキャン ノードへのベクトル化された列データのロードが容易になります。列ストレージ + ベクトル化された実行エンジンは、OLAP パフォーマンスへの扉を開く黄金の鍵の 1 つです。
行ストレージテーブルと列ストレージテーブルについて
行格納テーブルは、タプルを行単位で Page ページに格納します。これは主に、データが頻繁に更新され、多くの追加、削除、変更があり、クエリ結果にテーブルの複数の列が含まれる TP シナリオで使用されます。
列ストレージ テーブルは列に格納され、各列のデータはファイルに格納されます。主に AP シナリオで使用されます。
- テーブルの列の数が多く、アクセスされる列の数が少なく、IO 操作の数が削減されます。
- 列データが均一になり、データ圧縮率が向上します
- カラムバッチデータに基づく演算、CPUキャッシュヒット率が高い
実行フレームワーク
エグゼキュータは、オプティマイザとストレージ エンジン間の対話のハブです。オプティマイザが生成した実行計画ツリーを入力として、ストレージエンジンからデータにアクセスし、計画に従って各種実行演算子を動作させてデータ処理を実現します。パイプライン モードを使用すると、行エグゼキューターは一度に 1 つのタプルを操作し、列エグゼキューターは一度に 1 つのバッチを操作します。上位層が下位層を駆動し、データが実行ツリーを上流に流れることを可能にします。さまざまなデータ処理のための実行オペレーターを提供します。以下の図は、トップダウンの制御フローとボトムアップのデータ フローを示しています。
エグゼキュータの実行プロセスは、次の 3 つのステップに分けることができます。
- エグゼキュータの初期化: エグゼキュータのグローバル ステータス情報資産を構築し、プラン ツリーの各ノードを再帰的に走査し、その実行ステータス情報 planstate を初期化します。
- エグゼキュータの実行: 行エンジンとベクトル化エンジンの入り口は独立しています。プラン ツリーのルート ノードから開始して、階層ごとに処理した後、葉ノードまで再帰的に移動します。ノード演算子を使用すると、タプル/バッチがなくなるまで、結果のタプル/バッチが返されます。
- エグゼキューターのクリーンアップ: エグゼキューターのグローバル ステータス情報をリサイクルし、各プラン ノードの実行ステータスをクリーンアップします。
列エグゼキュータ
行エグゼキューターの問題は、CPU 処理のほとんどが実際にデータを処理するのではなく、プラン ツリーの走査プロセスにあり、実効的な CPU 使用率が低いことです。列ストレージ テーブルの固有のアプリケーション シナリオでは、OLAP シナリオでのパフォーマンス向上を真に活用するには、サポートされているベクトル化エンジンが必要です。したがって、列エグゼキューターを変換する基本的な考え方は、一度に 1 列のデータを処理することです。
行エグゼキュータと同様に、ベクトル化された実行エンジン スケジューラはパイプライン モードに従いますが、オペレータ間の各処理とデータ転送は一度に 1 バッチ (つまり 1000 行のデータ) であるため、CPU ヒット率が向上し、IO 読み取り操作が減少します。 。列実行プログラム VectorBatch のデータ フロー構造を次の図に示します。
行と列の混合: アダプター演算子
列ストレージ テーブルの一部のシナリオでは、string_to_array、listagg、string_agg などのベクトル化された実行エンジンがサポートされません。
GaussDB には、2 セットの行エンジンと列エンジンを自動的に切り替える機能があります。
列ストレージ データの場合、行エンジンしかない場合は、通常、実行エンジンが行ごとに処理できるように列データをタプルに再構築する必要があります。タプル変形プロセスは、列ストレージ データ クエリ処理のパフォーマンスに影響します。
ベクトル化された実行エンジンのパフォーマンス
行ストレージ エンジンと列ストレージ エンジンによる同じ式 x*(1-y) の計算パフォーマンスを比較すると、列ストレージ エンジンの Cstore Scan オペレーターは行ストレージの Seq Scan オペレーターよりも所要時間が 85% 少ないことがわかります。エンジン。
ベクトルコンピューティングの特徴は、一度に複数の値を計算し、関数呼び出しやコンテキストスイッチを削減し、CPU キャッシュとベクトル化された実行命令を最大限に活用してパフォーマンスを向上させることです。
ベクトル化された実行エンジンのパフォーマンス上の利点:
- 一度に 1 つのバッチで、より多くのデータを読み取り、IO 読み取りの数を削減します。
- Batch 内のレコード数が多いため、対応する CPU のキャッシュ ヒット率が増加します。
- パイプライン モード実行中の関数呼び出しの数が減少します。
- 列ストレージ テーブルと一致させて、タプルの変形、つまり列ストレージ データからタプルを再構築する時間のオーバーヘッドを削減します。
行/列エグゼキュータの演算子の比較
ベクトル化エンジンの実行演算子は、制御演算子、スキャン演算子、実体化演算子、接続演算子など、行実行エンジンと似ています。また、行実行ノードから継承されたノードによって表され、実行プロセスは再帰的になります。含まれる主なノードは、CStoreScan (シーケンシャル スキャン)、CStoreIndexScan (インデックス スキャン)、CStoreIndexHeapScan (ビットマップを使用してタプルを取得する)、Vecmaterial (具体化)、VecSort (並べ替え)、VecHashJoin (ベクトル化されたハッシュ接続) などです。これらの実行演算子については、以下で 1 つずつ説明します。
スキャンオペレーター
スキャン演算子はテーブル内のデータをスキャンするために使用され、上位ノードの入力としてタプルを取得するたびに、クエリ プラン ツリーのリーフ ノードに存在し、テーブルをスキャンするだけでなく、関数の結果セット、リンクされたリスト構造、およびクエリ結果セットをスキャンします。より一般的なスキャン演算子のいくつかを表に示します。
演算子 (行/列記憶演算子) | 意味 | 登場シーン |
---|---|---|
SeqScan/CStoreScan | シーケンシャルスキャン | 最も基本的なスキャン演算子。物理テーブルのスキャンに使用されます (インデックス支援なしの順次スキャン)。 |
IndexScan/CStoreIndexScan | インデックススキャン | 選択基準に含まれる属性にインデックスが作成されます |
IndexOnlyScan/CStoreIndexOnlyScan | インデックスから直接タプルを返す | インデックス列が結果セット列を完全にカバーします |
BitmapScan(BitmapIndexScan, BitmapHeapScan) / CStoreIndexHeapScan (CStoreIndexAnd, CStoreIndexOr,CStoreIndexCtidScan) | ビットマップを使用してタプルを取得する | BitmapIndexScan は属性のインデックスを使用してスキャンし、結果をビットマップとして返します。 BitmapHeapScan は BitmapIndexScan によって出力されたビットマップからタプルを取得します。 |
ティッドスキャン | タプル tid でタプルを取得する | 1.WHERE 条件(CTID = tid または CTID IN (tid1, tid2, …) など) ;2.UPDATE/DELETE … WHERE CURRENT OF カーソル |
サブクエリスキャン/Vecサブクエリスキャン | サブクエリスキャン | 別のクエリ プラン ツリー (サブプラン) をスキャン オブジェクトとして使用してタプルをスキャンする |
ファンクションスキャン | 関数スキャン | FROM 関数名 |
値スキャン | 値のリンクされたリストをスキャンします | VALUES 句で指定されたタプルのコレクションをスキャンします。 |
フォーリンスキャン/Vecフォーリンスキャン | 外部テーブルスキャン | 外部テーブルのクエリ |
CteScan/VecCteScan | CTEテーブルスキャン | SELECT クエリの WITH 句で定義されたサブクエリをスキャンする |
接続演算子
結合演算子は、リレーショナル代数の結合操作に対応します。テーブル t1 join t2 を例に挙げると、主な集中結合タイプは次のとおりです:内部結合、左結合、右結合、完全結合、セミ結合、アンチ結合、およびそれらの結合。実装メソッドにはNestloop 、HashJoin、MergeJoinが含まれます。
演算子 (行/列記憶演算子) | 意味 | 登場シーン |
---|---|---|
ネストループ/ベックネストループ | ネストされたループ接続、暴力的な接続、内部テーブルの行ごとのスキャン | 内部結合、左外部結合、セミ結合、アンチ結合 |
MergeJoin/VecMergeJoin | マージ接続(入力順)、内表と外表のソート、始端と終端の位置決め、タプルの結合を一括で行います。等結合 | 内部結合、左外部結合、右外部結合、完全外部結合、セミ結合、アンチ結合 |
ハッシュジョイン/Vecハッシュジョイン | ハッシュ結合では、内部テーブルと外部テーブルは結合列のハッシュ値を使用してハッシュ テーブルを作成し、同じ値が同じハッシュ バケット内に存在する必要があります。等結合 | 内部結合、左外部結合、右外部結合、完全外部結合、セミ結合、アンチ結合 |
実体化演算子
マテリアライズされた演算子は、タプルをキャッシュできるノードのタイプです。実行中、多くの拡張物理演算子は、操作する前にまずすべてのタプルを取得する必要があります (集約関数演算、インデックス支援なしの並べ替えなど)。これには、実体化演算子を使用してタプルをキャッシュする必要があります。
演算子 (行/列記憶演算子) | 意味 | 登場シーン |
---|---|---|
素材/ベック素材 | 具現化する | 子ノードの結果をキャッシュする |
ソート/ベックソート | 選別 | ORDER BY 句、接続操作、グループ化操作、集合操作、Unique 付き |
グループ/VecGroup | グループ化操作 | GROUP BY子句 |
Agg/VecAggregation | 集計関数の実行 | 1. COUNT/SUM/AVG/MAX/MIN などの集計関数。 2. DISTINCT 句。 4. GROUP BY 句。 |
WindowAgg/VecWindowAgg | 窓関数 | WINDOW句 |
ユニーク/Vecユニーク | 重複排除 (下位レベルがソートされています) | 1. DISTINCT 句 2. UNION 重複排除 |
ハッシュ | HashJoin ヘルパー ノード | ハッシュテーブルを構築しHashJoinと連携する |
SetOp/VecSetOp | 収集操作の処理 | 交差/すべて交差、除く/すべて除く |
ロック行 | 行レベルのロックの処理 | …を選択して共有/更新してください |
制御オペレータ
制御演算子は、特殊な状況を処理し、特殊な実行プロセスを実装するために使用されるノードのタイプです。
演算子 (行/列記憶演算子) | 意味 | 登場シーン |
---|---|---|
結果/VecResult | 直接計算する | 1. テーブル スキャンは含まれません。 2. INSERT ステートメントに VALUES 句が 1 つだけあります。 3. Append/MergeAppend がプラン ルート ノードである場合 (投影プッシュアップ)。 |
テーブルの変更 | 上位ノードの INSERT/UPDATE/DELETE | 挿入/更新/削除 |
アペンド/VecAppend | 追加 | 1. UNION(ALL) 2. 継承テーブル |
マージ追加 | 追加 (入力順序) | 1. UNION(ALL) 2. 継承テーブル |
再帰ユニオン | WITH 句で再帰的に定義された UNION サブクエリの処理 | WITH RECURSIVE … SELECT … ステートメント |
ビットマップと | ビットマップ論理積演算 | 多次元インデックススキャン用の BitmapScan |
ビットマップまたは | ビットマップ論理和演算 | 多次元インデックススキャン用の BitmapScan |
リミット/Vecリミット | LIMIT句の処理 | オフセット … リミット … |
その他のオペレーター
他の演算子には、Stream 演算子や RemoteQuery などの演算子が含まれます。
演算子 (行/列記憶演算子) | 意味 | 登場シーン |
---|---|---|
ストリーム | マルチノードのデータ交換 | 分散クエリ プランを実行すると、ノード間でデータ交換が行われます。 |
パーティションイテレータ | 分割されたイテレータ | パーティションテーブルスキャン、各パーティションを繰り返しスキャン |
VecToRow/RowToVec | 列から行へ/行から列へ | ランクとランクの混合シーン |
DfsScan / DfsIndexScan | HDFS テーブル (インデックス) スキャン | HDFSテーブルスキャン |
Gaussdb ベクトル化の進化
第一世代のベクトル化エンジンの後、GaussDB はより高性能なベクトル化エンジン、Sonic ベクトル化エンジンと Turbo ベクトル化エンジンを進化させました。
OLAP の実行パフォーマンスを向上させるために、GaussDB は列ストレージ + ベクトル化された実行エンジンとバッチ計算を目指して進化し続けています。
- ストリームオペレータ+分散実行フレームワークにより複数ノード間のデータフローをサポート
- SMP、ノード内のマルチスレッド並列処理、アイドル状態のハードウェア リソースを最大限に活用
- LLVM テクノロジー、新しいコード生成フレームワーク、JIT (ジャスト イン タイム) コンパイラーにより、タプル変形のボトルネックが解消されます。
- Sonic ベクトル化エンジンは、HashAgg 演算子と HashJoin 演算子をさらにベクトル化し、各列の異なるタイプに従ってデータを計算するための異なる配列を実装します。
- 新世代の Turbo ベクトル化エンジンは、Sonic エンジンに基づいてほとんどの演算子をさらにベクトル化し、Null 最適化、大きな整数の最適化、ストリームの最適化、ソートの最適化などが追加され、パフォーマンスがさらに向上します。
要約する
この記事では、GaussDB ベクトル化実行エンジンを紹介し、そのフレームワーク、原理、各演算子の概要、パフォーマンスの向上について詳しく説明します。
クリックしてフォローし、できるだけ早くHuawei Cloudの新しいテクノロジーについて学びましょう~
私はオープンソース紅蒙を諦めることにしました 、オープンソース紅蒙の父である王成露氏:オープンソース紅蒙は 中国の基本ソフトウェア分野における唯一の建築革新産業ソフトウェアイベントです - OGG 1.0がリリースされ、ファーウェイがすべてのソースコードを提供します。 Google Readerが「コードクソ山」に殺される Fedora Linux 40が正式リリース 元Microsoft開発者:Windows 11のパフォーマンスは「ばかばかしいほど悪い」 馬化騰氏と周宏毅氏が「恨みを晴らす」ために握手 有名ゲーム会社が新たな規制を発行:従業員の結婚祝いは10万元を超えてはならない Ubuntu 24.04 LTSが正式リリース Pinduoduoが不正競争の罪で判決 賠償金500万元