INSERT INTO は、標準 SQL 構文を使用して Doris テーブルにデータをロードします。各文は MySQL プロトコル経由で独立したインポートジョブとして実行され、結果を同期的に返します。
本トピックの一部情報は Apache Doris に由来します。詳細については、「Apache Doris の概要」をご参照ください。
構文
Doris は次の 2 種類の INSERT INTO 構文をサポートしています。
| 構文 | ユースケース |
|---|---|
INSERT INTO tbl SELECT ... | 抽出・変換・ロード (ETL) ワークフローや本番データパイプライン |
INSERT INTO tbl (col1, col2, ...) VALUES (1, 2, ...) | デモおよび機能検証のみ |
VALUES 構文はデモ専用です。テスト環境や本番環境では使用しないでください。
共通テーブル式
INSERT INTO 文で共通テーブル式 (CTE) を使用する場合は、WITH LABEL とカラムリストを指定するか、CTE をサブクエリで囲んでください。
-- オプション 1: WITH LABEL + カラムリスト
INSERT INTO tbl1 WITH LABEL label1
WITH cte1 AS (SELECT * FROM tbl1), cte2 AS (SELECT * FROM tbl2)
SELECT k1 FROM cte1 JOIN cte2 WHERE cte1.k1 = 1;
INSERT INTO tbl1 (k1)
WITH cte1 AS (SELECT * FROM tbl1), cte2 AS (SELECT * FROM tbl2)
SELECT k1 FROM cte1 JOIN cte2 WHERE cte1.k1 = 1;
-- オプション 2: CTE をサブクエリで囲む
INSERT INTO tbl1 (k1)
SELECT * FROM (
WITH cte1 AS (SELECT * FROM tbl1), cte2 AS (SELECT * FROM tbl2)
SELECT k1 FROM cte1 JOIN cte2 WHERE cte1.k1 = 1
) AS ret;構文の詳細については、HELP INSERT を実行してください。
インポートジョブの実行
MySQL プロトコルを使用して INSERT INTO 文を送信します。
INSERT INTO tbl2 WITH LABEL label1 SELECT * FROM tbl3;
INSERT INTO tbl1 VALUES ("qweasdzxcqweasdzxc"), ("a");結果の解釈
INSERT INTO は結果を同期的に返します。その形式は結果によって異なります。
判定ロジック
| 結果 | 意味 | 次のステップ |
|---|---|---|
ERROR 1064 (HY000) | インポート失敗 | メッセージ内のエラー URL を確認します |
Query OK, 0 rows affected | 空の結果セット。データがインポートされていません | — |
Query OK, N rows affected + status: visible | インポート成功 | — |
Query OK, N rows affected + status: committed | データはインポートされたが一時的に非表示 | SHOW TRANSACTION を実行して可視性をポーリングします |
Query OK, N rows affected + warnings > 0 | 一部の行がフィルターされました | SHOW LOAD を実行してエラー URL を取得します |
空の結果セット
SELECT 句が行を返さない場合:
mysql> INSERT INTO tbl1 SELECT * FROM empty_tbl;
Query OK, 0 rows affected (0.02 sec)Query OK は文が正常に実行されたことを示します。0 rows affected はデータがインポートされていないことを意味します。
インポート成功
データがインポートされた場合、Doris はサマリー行と JSON 文字列を返します。
mysql> INSERT INTO tbl1 SELECT * FROM tbl2;
Query OK, 4 rows affected (0.38 sec)
{'label':'insert_8510c568-9eda-4173-9e36-6adc7d35****', 'status':'visible', 'txnId':'4005'}
mysql> INSERT INTO tbl1 WITH LABEL my_label1 SELECT * FROM tbl2;
Query OK, 4 rows affected (0.38 sec)
{'label':'my_label1', 'status':'visible', 'txnId':'4005'}
mysql> INSERT INTO tbl1 SELECT * FROM tbl2;
Query OK, 2 rows affected, 2 warnings (0.31 sec)
{'label':'insert_f0747f0e-7a35-46e2-affa-13a235f4****', 'status':'committed', 'txnId':'4005'}JSON フィールドの説明は以下のとおりです。
| フィールド | 説明 |
|---|---|
label | インポートジョブの識別子。WITH LABEL で指定しない場合、自動生成されます。1 つのデータベース内で各インポートジョブに対して一意です。 |
status | データの可視性:visible(データが読み取り可能)または committed(一時的に非表示。後に可視化されます)。 |
txnId | インポートのトランザクション ID。 |
err | 予期しないエラーが発生した場合のエラーメッセージ。 |
インポート失敗
インポートが失敗した場合、データはロードされず、エラーが返されます。
mysql> INSERT INTO tbl1 SELECT * FROM tbl2 WHERE k1 = "a";
ERROR 1064 (HY000): all partitions have no load data. url: http://10.74.xx.xx:8042/api/_load_error_log?file=__shard_2/error_log_insert_stmt_ba8bb9e158e4879-ae8de8507c0b****エラーメッセージ内の URL は、そのインポート試行のエラーログを指しています。
インポートステータスの確認
同一セッション内
INSERT INTO 文の直後に SHOW LAST INSERT を実行すると、現在のセッションで最新のインポート結果を取得できます。
mysql> SHOW LAST INSERT\G
*************************** 1. row ***************************
TransactionId: 640**
Label: insert_ba8f33aea9544866-8ed77e2844d0****
Database: default_cluster:db1
Table: t1
TransactionStatus: VISIBLE
LoadedRows: 2
FilteredRows: 0SHOW LAST INSERT は同一セッション内でのみ結果を返します。セッションが閉じられたり置き換えられたりした場合、空の結果セットが返されます。
MySQL クライアントライブラリ使用時
一部の MySQL クライアントライブラリは INSERT INTO 応答から JSON 文字列を公開しません。そのような場合は、各 INSERT INTO 文の後に SHOW LAST INSERT を実行して、プログラムから結果を取得してください。
行がフィルターされた場合
warnings > 0 の場合、SHOW LOAD を実行してエラーログの URL を取得します。
SHOW LOAD WHERE label="xxx";ステータスが committed の場合
committed ステータスは一時的です。TransactionStatus が VISIBLE になるまで、SHOW TRANSACTION をポーリング実行してください。
SHOW TRANSACTION WHERE id=4005;構成
FE 構成
| パラメーター | デフォルト | 説明 |
|---|---|---|
insert_load_default_timeout_second | 3600 (1 時間) | すべての INSERT INTO ジョブのタイムアウト時間 (秒単位)。この時間を超過すると、ジョブは CANCELLED 状態になります。すべてのジョブに適用され、ジョブごとのオーバーライドはできません。 |
タイムアウトを延長するには、FE 構成を変更します。
insert_load_default_timeout_second = <seconds>セッション変数
| 変数 | デフォルト | 説明 |
|---|---|---|
enable_insert_strict | false | インポートエラーに対する許容度を制御します。false:少なくとも 1 行がインポートされれば成功とみなされます(一部の行が失敗してもラベルが返されます)。true:いずれかの行がインポートに失敗すると全体が失敗します。 |
query_timeout | — | クエリレベルのタイムアウト時間 (秒単位)。INSERT INTO 文は、insert_load_default_timeout_second に加えて、この変数の影響も受けます。 |
セッション変数は次のように設定します。
SET enable_insert_strict = true;
SET query_timeout = <seconds>;ベストプラクティス
適切な構文の選択
| シナリオ | 推奨構文 |
|---|---|
| 小規模データで Doris の機能を検証する | INSERT INTO ... VALUES |
| Doris 内での ETL 処理 (あるテーブルをクエリし、別のテーブルに書き込む) | INSERT INTO ... SELECT |
| 外部ソース (MySQL 外部テーブル、Hadoop 分散ファイルシステム (HDFS) をマッピングするブローカー外部テーブル) からのデータロード | INSERT INTO ... SELECT |
タイムアウトの見積もりと設定
Doris は INSERT INTO インポートのデータサイズに上限を設けていません。大規模データセットの場合は、ジョブ実行前にデフォルトの 1 時間タイムアウトが十分かどうかを計算してください。
次の数式を出発点として使用します。
推定時間 (秒) = データサイズ (GB) / インポート速度 (MB/秒)インポート速度 にはクラスターの実際の平均速度を代入してください。一般的な参考値は 10 MB/秒ですが、実際のスループットは環境により異なります。
推定時間が 3,600 秒を超える場合は、ジョブ送信前にフロントエンド (FE) の insert_load_default_timeout_second を増加させてください。
完全な例
シナリオ:store_sales から bj リージョンの約 10 GB のデータを bj_store_sales にインポートします。クラスターの平均インポート速度は 5 MB/秒です。
テーブルスキーマ:
-- ソーステーブル
store_sales (id, total, user_id, sale_timestamp, region)
-- ターゲットテーブル
bj_store_sales (id, total, user_id, sale_timestamp)ステップ 1. 推定インポート時間を計算し、タイムアウトを調整します。
10 GB / 5 MB/秒 = 2000 秒FE 構成を設定します。
insert_load_default_timeout_second = 2000ステップ 2. インポートを実行します。
INSERT INTO bj_store_sales WITH LABEL `label`
SELECT id, total, user_id, sale_timestamp
FROM store_sales
WHERE region = "bj";