INSERT INTO文
テーブルにデータを挿入します。
構文
挿入するカラムのリストは、(c1, c2, c3)を使用して指定できます。また、*のようなカラム マッチャーや、APPLY、EXCEPT、REPLACEといった修飾子を使った式も使用できます。
たとえば、次のテーブルを考えます:
すべてのカラムにデータを挿入したいが、カラムbは除外したい場合、EXCEPTキーワードを使用して行うことができます。上記の構文を参照すると、指定したカラム数((c1, c3))と同じだけの値(VALUES (v11, v13))を挿入する必要があります:
この例では、挿入された2番目の行がaとcカラムに指定された値で埋められ、bカラムはデフォルト値で埋められているのが分かります。また、デフォルト値を挿入するためにDEFAULTキーワードを使用することも可能です:
カラムのリストにすべての既存のカラムが含まれていない場合、残りのカラムには次の値が設定されます:
- テーブル定義で指定された
DEFAULT式から計算された値。 DEFAULT式が定義されていない場合はゼロや空文字列。
データは、ClickHouseがサポートする任意のフォーマットでINSERTに渡すことができます。フォーマットはクエリで明示的に指定する必要があります:
たとえば、次のクエリフォーマットは基本的なINSERT ... VALUESバージョンと同じです:
ClickHouseは、データの前にすべてのスペースと1行の改行(もしあれば)を削除します。クエリを形成する際には、データがクエリ演算子の後の新しい行に配置されることをお勧めします。データがスペースで始まる場合は特に重要です。
例:
コマンドラインクライアントやHTTPインターフェースを使用することで、クエリとは別にデータを挿入することができます。
INSERTクエリにSETTINGSを指定したい場合は、FORMAT句の前にそれを行う必要があります。なぜならFORMAT format_nameの後はすべてデータとして扱われるからです。例えば:
制約
テーブルに制約がある場合、挿入されたデータの各行に対してそれらの式がチェックされます。いずれかの制約が満たされない場合、サーバーは制約名と式を含む例外を発生させ、クエリは停止します。
SELECTの結果を挿入する
構文
カラムはSELECT句の位置に従ってマッピングされます。しかし、SELECT式の中の名前とINSERT用のテーブルでの名前は異なっていても構いません。必要に応じて型のキャストが行われます。
Values形式以外のデータフォーマットでは、now()や1 + 2などの式へ値を設定することはできません。Values形式は限られた使用の表現を許可しますが、この場合は非効率なコードが使用されるため推奨されません。
データ部分を変更するための他のクエリはサポートされていません:UPDATE、DELETE、REPLACE、MERGE、UPSERT、INSERT UPDATE。
ただし、ALTER TABLE ... DROP PARTITIONを使用して古いデータを削除することはできます。
SELECT句にテーブル関数input()が含まれている場合、FORMAT句はクエリの最後に指定する必要があります。
ノンヌルデータ型のカラムにNULLの代わりにデフォルト値を挿入するには、insert_null_as_default設定を有効にします。
INSERTはCTE(共通テーブル式)もサポートしています。たとえば、次の二つのステートメントは同等です:
ファイルからデータを挿入する
構文
上記の構文を使用して、クライアント側に保存されたファイルからデータを挿入します。file_nameとtypeは文字列リテラルです。入力ファイルのフォーマットはFORMAT句で設定する必要があります。
圧縮ファイルがサポートされています。圧縮タイプはファイル名の拡張子によって検出されます。また、COMPRESSION句で明示的に指定することも可能です。サポートされているタイプは: 'none'、'gzip'、'deflate'、'br'、'xz'、'zstd'、'lz4'、'bz2'です。
この機能はコマンドラインクライアントやclickhouse-localで利用できます。
例
FROM INFILEを使用した単一ファイル
次のクエリをコマンドラインクライアントを使用して実行します:
結果:
グロブを使用したFROM INFILEによる複数ファイル
この例は前の例に非常に似ていますが、FROM INFILE 'input_*.csv'を使用して複数のファイルから挿入を行います。
テーブル関数を使用した挿入
データはテーブル関数で参照されるテーブルに挿入できます。
構文
例
次のクエリではremoteテーブル関数が使用されています:
結果:
ClickHouse Cloudへの挿入
デフォルトでは、ClickHouse Cloud上のサービスは高可用性のために複数のレプリカを提供します。サービスに接続すると、これらのレプリカの1つに接続されます。
INSERTが成功すると、データは基盤となるストレージに書き込まれます。ただし、レプリカがこれらの更新を受け取るには少し時間がかかる場合があります。したがって、他のレプリカの1つでSELECTクエリを実行する異なる接続を使用すると、更新されたデータがまだ反映されない場合があります。
select_sequential_consistencyを使用して、レプリカが最新の更新を受け取るよう強制することができます。この設定を使ったSELECTクエリの例は次のとおりです:
select_sequential_consistencyを使用すると、ClickHouse Keeper(ClickHouse Cloud内部で使用される)がより負荷高くなり、サービスの負荷に応じてパフォーマンスが遅くなる可能性があることに注意してください。この設定は必要がない限り有効にしないことをお勧めします。推奨アプローチは、同じセッションで読み取り/書き込みを実行するか、ネイティブプロトコルを使用するクライアントドライバを使用すること(したがって、スティッキー接続がサポートされます)です。
レプリケーションされたセットアップへの挿入
レプリケーションされたセットアップでは、データは複製された後、他のレプリカで利用可能になります。データは、INSERT 直後にすぐに複製が開始されます(他のレプリカにダウンロードされます)。これは、データがすぐに共有ストレージに書き込まれ、レプリカがメタデータの変更にサブスクライブするClickHouse Cloudとは異なります。
レプリケーションされたセットアップでは、INSERTにかなりの時間(約1秒程度)がかかる場合があることに注意が必要です。これは、分散合意のためにClickHouse Keeperへのコミットが必要なためです。S3をストレージとして使用する場合にも追加の待機時間が発生します。
パフォーマンスの考慮事項
INSERTは入力データを主キーでソートし、パーティションキーでパーティションに分割します。一度に複数のパーティションにデータを挿入すると、INSERTクエリのパフォーマンスが大きく低下することがあります。これを避けるためには:
- 1回に100,000行など、かなり大きなバッチでデータを追加します。
 - データをClickHouseにアップロードする前に、パーティションキーでグループ化します。
 
リアルタイムでデータが追加される場合や、通常時間でソートされたデータをアップロードする場合は、パフォーマンスが低下することはありません。
非同期挿入
小さいが頻繁な挿入を使用して非同期にデータを挿入することが可能です。そのような挿入からのデータはバッチにまとめられ、安全にテーブルに挿入されます。非同期挿入を使用するには、async_insert設定を有効にします。
async_insertまたはBufferテーブルエンジンを使用すると、追加のバッファリングが発生します。
大量または長時間の挿入
大量のデータを挿入する場合、ClickHouseは「圧縮」と呼ばれるプロセスを通じて書き込み性能を最適化します。メモリ内に挿入された小さなデータブロックはマージされ、大きなブロックに圧縮されてからディスクに書き込まれます。圧縮は、各書き込み操作に伴うオーバーヘッドを軽減します。このプロセスでは、挿入されたデータはClickHouseがmax_insert_block_size行の書き込みを完了した後にクエリ可能となります。
その他の関連項目