メインコンテンツまでスキップ
メインコンテンツまでスキップ

データ型を選択

One of the core reasons for ClickHouse's query performance is its efficient data compression. Less data on disk results in faster queries and inserts by minimizing I/O overhead. ClickHouse's column-oriented architecture naturally arranges similar data adjacently, enabling compression algorithms and codecs to reduce data size dramatically. To maximize these compression benefits, it's essential to carefully choose appropriate data types.

Compression efficiency in ClickHouse depends mainly on three factors: the ordering key, data types, and codecs, all defined through the table schema. Choosing optimal data types yields immediate improvements in both storage and query performance.

Some straightforward guidelines can significantly enhance the schema:

  • 厳密な型を使用する: 常にカラムに正しいデータ型を選択してください。数値および日付フィールドには、一般的な文字列型ではなく、適切な数値および日付型を使用する必要があります。これにより、フィルタリングや集計に対する正しい意味が確保されます。

  • Nullableカラムを避ける: Nullableカラムは、null値を追跡するための別のカラムを維持することによる追加のオーバーヘッドを引き起こします。空とnullの状態を区別するために明示的に必要ない限り、Nullableを使用しないでください。それ以外の場合、デフォルト値やゼロ相当の値で通常は十分です。この型を必要に応じて避けるべき理由については、Nullableカラムを避けるを参照してください。

  • 数値精度を最小限に抑える: 予想されるデータ範囲をまだ満たす最小のビット幅を持つ数値型を選択してください。たとえば、負の値が必要ない場合、Int32の代わりにUInt16を選択することをお勧めしますし、範囲が0〜65535に収まる場合に推奨されます。

  • 日付および時間精度を最適化する: クエリの要件を満たす最も粗い日付または日時型を選択してください。日付のみのフィールドにはDateまたはDate32を使用し、ミリ秒やそれ以上の精度が重要でない限り、DateTimeの代わりにDateTime64を使用してください。

  • LowCardinalityおよび特殊型を活用する: 約10,000未満のユニーク値のカラムには、辞書エンコーディングを用いてストレージを大幅に削減するためにLowCardinality型を使用してください。同様に、カラム値が厳密に固定長の文字列である場合のみFixedStringを使用し、有限の値のセットを持つカラムにはEnum型を好んで使用して、効率的なストレージと組み込みのデータ検証を可能にします。

  • データ検証用のEnums: Enum型は、列挙型を効率的にエンコードするために使用できます。Enumsは、保存する必要のあるユニーク値の数に応じて8ビットまたは16ビットとなります。挿入時の関連する検証が必要な場合(未宣言の値は拒否されます)や、Enum値の自然な順序を利用したクエリを実行したい場合には、これを使用することを検討してください。例として、ユーザーの反応を含むフィードバックカラムEnum(':(' = 1, ':|' = 2, ':)' = 3)を想像してください。

ClickHouseは、型の最適化を簡素化するための組み込みツールを提供しています。たとえば、スキーマ推論は最初の型を自動的に特定できます。Parquet形式で公開されているStack Overflowデータセットを考慮してください。DESCRIBEコマンドを使用して簡単なスキーマ推論を実行すると、初期の最適化されていないスキーマが提供されます。

注記

デフォルトでは、ClickHouseはこれを同等のNullable型にマッピングします。これは、スキーマが行のサンプルに基づいているため、推奨されます。

注記

以下に、stackoverflow/parquet/postsフォルダー内のすべてのファイルを読み込むためにグロブパターン*.parquetを使用しています。

初期のシンプルなルールをpostsテーブルに適用することで、各カラムに最適な型を特定できます:

ColumnIs NumericMin, MaxUnique ValuesNullsCommentOptimized Type
PostTypeIdYes1, 88NoEnum('Question' = 1, 'Answer' = 2, 'Wiki' = 3, 'TagWikiExcerpt' = 4, 'TagWiki' = 5, 'ModeratorNomination' = 6, 'WikiPlaceholder' = 7, 'PrivilegeWiki' = 8)
AcceptedAnswerIdYes0, 7828517012282094YesNullを0の値と区別するUInt32
CreationDateNo2008-07-31 21:42:52.667000000, 2024-03-31 23:59:17.697000000-Noミリ秒単位の精度は不要、DateTimeを使用DateTime
ScoreYes-217, 349703236NoInt32
ViewCountYes2, 13962748170867NoUInt32
BodyNo--NoString
OwnerUserIdYes-1, 40569156256237YesInt32
OwnerDisplayNameNo-181251YesNullは空文字列と見なすString
LastEditorUserIdYes-1, 99999931104694Yes0は使われていない値でNullに使用可能Int32
LastEditorDisplayNameNo-70952YesNullは空文字列として見なす。LowCardinalityを試したが利益なしString
LastEditDateNo2008-08-01 13:24:35.051000000, 2024-04-06 21:01:22.697000000-Noミリ秒単位の精度は不要、DateTimeを使用DateTime
LastActivityDateNo2008-08-01 12:19:17.417000000, 2024-04-06 21:01:22.697000000-Noミリ秒単位の精度は不要、DateTimeを使用DateTime
TitleNo--NoNullは空文字列として見なすString
TagsNo--NoNullは空文字列として見なすString
AnswerCountYes0, 518216NoNullと0は同一扱いUInt16
CommentCountYes0, 135100NoNullと0は同一扱いUInt8
FavoriteCountYes0, 2256YesNullと0は同一扱いUInt8
ContentLicenseNo-3NoLowCardinalityがFixedStringよりも優れていますLowCardinality(String)
ParentIdNo-20696028YesNullは空文字列として見なすString
CommunityOwnedDateNo2008-08-12 04:59:35.017000000, 2024-04-01 05:36:41.380000000-YesNullの場合はデフォルト1970-01-01を考慮。ミリ秒単位の精度は不要、DateTimeを使用DateTime
ClosedDateNo2008-09-04 20:56:44, 2024-04-06 18:49:25.393000000-YesNullの場合はデフォルト1970-01-01を考慮。ミリ秒単位の精度は不要、DateTimeを使用DateTime
tip

カラムの型を特定するには、その数値範囲とユニーク値の数を理解することが必要です。すべてのカラムの範囲および異なる値の数を見つけるには、ユーザーはシンプルなクエリSELECT * APPLY min, * APPLY max, * APPLY uniq FROM table FORMAT Verticalを使用できます。これをデータの少ないサブセットに対して実行することをお勧めします。これは高コストです。

これにより、次のような最適化されたスキーマが得られます(型に関して):

Nullableカラムを避ける

Nullable カラム (例: Nullable(String)) は UInt8 型の別のカラムを作成します。この追加のカラムは、ユーザーが Nullable カラムを操作するたびに処理される必要があります。これにより追加のストレージスペースが使用され、ほぼ常にパフォーマンスに悪影響を与えます。

Nullable カラムを避けるために、そのカラムにデフォルト値を設定することを検討してください。例えば、次の代わりに:

次のように使用します:

あなたのユースケースを考慮すると、デフォルト値が不適切な場合もあります。