ClickHouse/docs/ja/sql-reference/statements/insert-into.md
2024-11-18 11:58:58 +09:00

14 KiB
Raw Blame History

INSERT INTO ステートメント

テーブルにデータを挿入します。

構文

INSERT INTO [TABLE] [db.]table [(c1, c2, c3)] [SETTINGS ...] VALUES (v11, v12, v13), (v21, v22, v23), ...

挿入するカラムの一覧を (c1, c2, c3) で指定できます。また、*APPLY, EXCEPT, REPLACE などの修飾子を使用したカラムマッチャーの式も使用可能です。

例えば、以下のテーブルを考えます:

SHOW CREATE insert_select_testtable;
CREATE TABLE insert_select_testtable
(
    `a` Int8,
    `b` String,
    `c` Int8
)
ENGINE = MergeTree()
ORDER BY a
INSERT INTO insert_select_testtable (*) VALUES (1, 'a', 1) ;

すべてのカラムにデータを挿入し、'b' カラムを除外したい場合は、丸括弧内に選んだカラムの数だけ値を渡す必要があります:

INSERT INTO insert_select_testtable (* EXCEPT(b)) Values (2, 2);
SELECT * FROM insert_select_testtable;
┌─a─┬─b─┬─c─┐
│ 2 │   │ 2 │
└───┴───┴───┘
┌─a─┬─b─┬─c─┐
│ 1 │ a │ 1 │
└───┴───┴───┘

この例では、2行目で挿入された行は、ac カラムが渡された値で埋められ、b カラムはデフォルト値で埋められています。DEFAULT キーワードを使用してデフォルト値を挿入することも可能です:

INSERT INTO insert_select_testtable VALUES (1, DEFAULT, 1) ;

カラムのリストにすべての既存カラムが含まれていない場合、残りのカラムは以下で埋められます:

  • テーブル定義で指定されている DEFAULT 式から計算された値。
  • DEFAULT 式が定義されていない場合は、ゼロと空文字列。

データは ClickHouse がサポートする任意のフォーマットINSERT に渡すことができます。クエリでフォーマットを明示的に指定する必要があります:

INSERT INTO [db.]table [(c1, c2, c3)] FORMAT format_name data_set

例えば、次のクエリフォーマットは基本的な INSERT ... VALUES と同じです:

INSERT INTO [db.]table [(c1, c2, c3)] FORMAT Values (v11, v12, v13), (v21, v22, v23), ...

ClickHouse はデータの前のすべてのスペースと1行の改行存在する場合を削除します。クエリを形成する際、データをクエリオペレータの後に新しい行に置くことをお勧めしますデータがスペースで始まる場合は重要です

例:

INSERT INTO t FORMAT TabSeparated
11  Hello, world!
22  Qwerty

データをクエリから分離して挿入するために、コマンドラインクライアントHTTPインターフェースを使用できます。

:::note INSERT クエリに SETTINGS を指定したい場合は、FORMAT 節の 前に 設定する必要があります。なぜなら、FORMAT format_name 以降はすべてデータと見なされるからです。例:

INSERT INTO table SETTINGS ... FORMAT format_name data_set

:::

制約

テーブルに制約がある場合、その式は挿入データの各行に対してチェックされます。それらの制約のいずれかが満たされていない場合、サーバーは制約名と式を含む例外を発生させ、クエリは中断されます。

SELECT の結果の挿入

構文

INSERT INTO [TABLE] [db.]table [(c1, c2, c3)] SELECT ...

カラムは SELECT 節での位置に従ってマッピングされます。しかし、SELECT 式と INSERT のためのテーブルでの名前は異なる場合があります。必要に応じて型キャスティングが行われます。

Values 以外のデータフォーマットは、now(), 1 + 2 などのような式に値を設定することを許可しません。Values フォーマットは式の限定的な使用を許可しますが、これは推奨されません。なぜなら、この場合、非効率的なコードが使用されるからです。

他のデータパーツを修正するクエリはサポートされていません:UPDATE, DELETE, REPLACE, MERGE, UPSERT, INSERT UPDATE。ただし、ALTER TABLE ... DROP PARTITION を使用して古いデータを削除できます。

SELECT 節がテーブル関数 input() を含む場合は、FORMAT 節をクエリの最後に指定する必要があります。

NULL を持つ非nullableなデータタイプのカラムに代わりにデフォルト値を挿入するには、insert_null_as_default 設定を有効にします。

INSERT はまた、CTE共通テーブル式をサポートしています。例えば、以下の2つの文は同等です

INSERT INTO x WITH y AS (SELECT * FROM numbers(10)) SELECT * FROM y;
WITH y AS (SELECT * FROM numbers(10)) INSERT INTO x SELECT * FROM y;

ファイルからデータを挿入

構文

INSERT INTO [TABLE] [db.]table [(c1, c2, c3)] FROM INFILE file_name [COMPRESSION type] [SETTINGS ...] [FORMAT format_name]

上記の構文を使用して、クライアント側に保存されているファイル、またはファイル群からデータを挿入します。file_nametype は文字列リテラルです。入力ファイルのフォーマットFORMAT 節で設定する必要があります。

圧縮ファイルはサポートされています。圧縮タイプはファイル名の拡張子で検出されます。もしくは、COMPRESSION 節で明示的に指定できます。サポートされているタイプは: 'none', 'gzip', 'deflate', 'br', 'xz', 'zstd', 'lz4', 'bz2'

この機能はコマンドラインクライアントおよびclickhouse-localで利用可能です。

FROM INFILE を使用した単一ファイル

以下のクエリをコマンドラインクライアントで実行します:

echo 1,A > input.csv ; echo 2,B >> input.csv
clickhouse-client --query="CREATE TABLE table_from_file (id UInt32, text String) ENGINE=MergeTree() ORDER BY id;"
clickhouse-client --query="INSERT INTO table_from_file FROM INFILE 'input.csv' FORMAT CSV;"
clickhouse-client --query="SELECT * FROM table_from_file FORMAT PrettyCompact;"

結果:

┌─id─┬─text─┐
│  1 │ A    │
│  2 │ B    │
└────┴──────┘

FROM INFILE を使用した複数ファイルのグロブ

この例は前のものと非常に似ていますが、FROM INFILE 'input_*.csv を使用して複数のファイルから挿入します。

echo 1,A > input_1.csv ; echo 2,B > input_2.csv
clickhouse-client --query="CREATE TABLE infile_globs (id UInt32, text String) ENGINE=MergeTree() ORDER BY id;"
clickhouse-client --query="INSERT INTO infile_globs FROM INFILE 'input_*.csv' FORMAT CSV;"
clickhouse-client --query="SELECT * FROM infile_globs FORMAT PrettyCompact;"

:::tip 複数のファイルを * で選択することに加え、範囲({1,2}{1..9})やその他のグロブ置換を使用できます。以下の3つすべてが上記の例で機能します

INSERT INTO infile_globs FROM INFILE 'input_*.csv' FORMAT CSV;
INSERT INTO infile_globs FROM INFILE 'input_{1,2}.csv' FORMAT CSV;
INSERT INTO infile_globs FROM INFILE 'input_?.csv' FORMAT CSV;

:::

テーブル関数を使ったデータの挿入

データはテーブル関数で参照されるテーブルに挿入できます。

構文

INSERT INTO [TABLE] FUNCTION table_func ...

次のクエリでは、remote テーブル関数を使用しています:

CREATE TABLE simple_table (id UInt32, text String) ENGINE=MergeTree() ORDER BY id;
INSERT INTO TABLE FUNCTION remote('localhost', default.simple_table)
    VALUES (100, 'inserted via remote()');
SELECT * FROM simple_table;

結果:

┌──id─┬─text──────────────────┐
│ 100 │ inserted via remote() │
└─────┴───────────────────────┘

ClickHouse Cloud へのデータ挿入

デフォルトでは、ClickHouse Cloud のサービスは高可用性のために複数のレプリカを提供します。サービスに接続すると、これらのレプリカのいずれかに接続が確立されます。

INSERT が成功すると、データは基盤となるストレージに書き込まれます。しかし、レプリカがこれらの更新を受け取るまでには時間がかかる場合があります。そのため、別の接続を使用してこれらの他のレプリカのいずれかで SELECT クエリを実行した場合、更新されたデータがまだ反映されていない可能性があります。

レプリカに最新の更新を受け取らせるためには、select_sequential_consistency を使用することが可能です。ここにその設定を使用した SELECT クエリの例を示します:

SELECT .... SETTINGS select_sequential_consistency = 1;

select_sequential_consistency を使用すると、ClickHouse Keeper に負荷がかかる可能性があり、サービスの負荷に応じてパフォーマンスが低下する可能性があることに注意してください。必要でない限り、この設定を有効にすることはお勧めしません。推奨されるアプローチは、同じセッションで読み取り/書き込みを実行するか、ネイティブプロトコルを使用するクライアントドライバを使用することです(これによりスティッキー接続がサポートされます)。

レプリケーション設定での挿入

レプリケーション設定では、データはレプリケーションされた後に他のレプリカで表示されます。データは INSERT 後すぐにレプリケーション(他のレプリカでダウンロード)を開始します。これは、データがすぐに共有ストレージに書き込まれ、レプリカがメタデータの変更を購読する ClickHouse Cloud とは異なります。

レプリケーション設定では、INSERTs が時には1秒程度のかなりの時間を要する可能性があることに注意してください。これは、分散コンセンサスのために ClickHouse Keeper にコミットする必要があるためです。S3 をストレージに使用することも、追加のレイテンシーを追加します。

パフォーマンスに関する考慮事項

INSERT は入力データを主キーでソートし、パーティションキーでパーティションに分割します。一度に複数のパーティションにデータを挿入すると、INSERT クエリのパフォーマンスが大幅に低下する可能性があります。これを避けるために:

  • 例えば 100,000 行のように、かなり大きなバッチでデータを追加する。
  • データをアップロードする前にパーティションキーでグループ化する。

以下の場合、パフォーマンスは低下しません:

  • データがリアルタイムで追加される。
  • 通常、時間でソートされたデータをアップロードする。

非同期挿入

小さくても頻繁に非同期でデータを挿入することが可能です。そのような挿入からのデータはバッチに結合され、安全にテーブルに挿入されます。非同期挿入を使用するには、async_insert 設定を有効にします。

async_insert または Buffer テーブルエンジン を使用することで、追加のバッファリングが発生します。

大規模または長時間実行の挿入

大量のデータを挿入するとき、ClickHouse は「スクワッシュ」と呼ばれるプロセスを通じて書き込みパフォーマンスを最適化します。メモリ内の小さなブロックの挿入データが結合され、ディスクに書き込まれる前に大きなブロックにスクワッシュされます。スクワッシュは、各書き込み操作に関連するオーバーヘッドを削減します。このプロセスでは、ClickHouse が各max_insert_block_size 行を書き込むのを完了した後、挿入されたデータがクエリ可能となります。

関連項目