Tableスキーマ設計の最適化
概要
Schema設計とチューニングにおいて、TableSchema設計は重要な部分であり、Tableエンジンの選択、パーティションとバケット列の選択、パーティションとバケットサイズの設定、キー列とフィールドタイプの最適化などが含まれます。適切なSchema設計が不足したシステムでは、データスキュー、システムの並列性とソート機能を十分に活用できない、などの問題が発生し、Dorisシステムがビジネスシステム内で真のパフォーマンス優位性を実現することを妨げる可能性があります。
詳細な設計原則については、Data Table Designセクションで詳しい情報を参照してください。本章では、実践的なケースの観点から、いくつかの典型的なシナリオでSchema設計の問題によって引き起こされるパフォーマンスのボトルネックを示し、ビジネスチューニングの参考として最適化の提案を提供します。
Case 1: Tableエンジンの選択
DorisはDuplicate、Unique、Aggregateの3つのTableモデルをサポートしています。その中で、UniqueはMerge-On-Read (MOR)とMerge-On-Write (MOW)にさらに分けることができます。
これらのTableモデルのクエリパフォーマンスは、最良から最悪の順に、Duplicate > MOW > MOR == Aggregateです。したがって、通常の状況下では、特別な要件がない場合、より良いクエリパフォーマンスのためにDuplicateTableが推奨されます。
ビジネスでデータ更新の要件がないが、クエリパフォーマンスに対する要求が高い場合は、Duplicate tableが推奨されます。
Case 2: バケット列の選択
Dorisはデータのバケット化をサポートしており、これはSchema内のバケットキーに基づいてデータを分散し、データバケットを形成することを意味します。
適切なバケット列を選択することは、生データの合理的な分散にとって重要であり、データスキューによって引き起こされるパフォーマンスの問題を効果的に防止します。同時に、DorisのColocate JoinとBucket Shuffle Join機能の利用を最大化し、Join操作のパフォーマンスを大幅に向上させます。
Tablet1のTable作成文を例に取ると、現在のバケット列はc2に設定されています。しかし、実際のデータインポートプロセス中に、列c2のすべての値がnullにデフォルト設定されている場合、64個のバケットが設定されていても、1つのバケットのみがすべてのデータを含むことになります。この極端なケースは重度のデータスキューを引き起こし、パフォーマンスのボトルネックを招きます。
CREATE TABLE `t1` (
`c1` INT NULL,
`c2` INT NULL
) ENGINE=OLAP
DUPLICATE KEY(`c1`)
DISTRIBUTED BY HASH(`c2`) BUCKETS 64
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
insert into t1 select number, null from numbers ('number'='10000000');
上記の状況に対応するため、bucketカラムをc2からc1に変更することで、適切なデータハッシュを実現し、システムの並列処理能力を最大化し、それによってチューニング目的を達成できます。
したがって、Schema設計フェーズでは、ビジネス担当者がビジネス特性に基づいて事前に合理的なbucketカラムを設計する必要があります。例えば、カラムc2のビジネス意味がnullや特定の値など、多数のスキューした値を含む可能性があることが事前に分かっている場合、これらのフィールドはbucketカラムとして避けるべきです。逆に、ユーザIDなど、ビジネス意味において適切なハッシュ特性を持つフィールドをbucketカラムとして選択すべきです。パフォーマンス問題のトラブルシューティングフェーズでは、以下のSQL文を使用してbucketフィールドにデータスキューがあるかどうかを確認し、それに応じて後続の最適化調整を行うことができます。
select c2,count(*) cnt from t1 group by c2 order by cnt desc limit 10;
bucket列にデータスキューの問題があるかどうかを確認してください。問題がある場合は、ビジネス的な意味で適切なハッシュ特性を持つフィールドでbucket列として置き換えてください。
良好な事前設計により、問題が発生した際の特定と修正のコストを大幅に削減できることは明らかです。そのため、ビジネス担当者がSchema設計フェーズにおいて厳密な設計とチェックを実施し、不要なコストの発生を回避することを強く推奨します。
ケース3:Key列の最適化
3つのTableモデルの中で、Table作成SchemaでDuplicate Key、Unique Key、またはAggregate Keyが明示的に指定されている場合、DorisはストレージレベルでKey列に基づいてデータがソートされることを保証します。この機能は、データクエリパフォーマンス最適化に新たなアイデアを提供します。具体的には、Schema設計フェーズにおいて、ビジネスクエリで等価クエリや範囲クエリに頻繁に使用される列をKey列として定義できれば、そのようなクエリの実行速度を大幅に向上させ、全体的なパフォーマンスを向上させることができます。
以下は、ビジネスクエリ要件の例のセットです:
select * from t1 where t1.c1 = 1;
select * from t1 where t1.c1 > 1 and t1.c1 < 10;
select * from t1 where t1.c1 in (1, 2, 3);
上記のビジネス要件とSchemaの設計、および後のTablet1の最適化において、クエリプロセスを高速化するためにカラムc1をKeyカラムとして設定することを検討することが推奨されます。以下に例を示します:
CREATE TABLE `t1` (
`c1` INT NULL,
`c2` INT NULL
) ENGINE=OLAP
DUPLICATE KEY(`c1`)
DISTRIBUTED BY HASH(`c2`) BUCKETS 10
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
ビジネスクエリで頻繁に使用されるカラムをキーカラムとして設定し、クエリプロセスを高速化してください。
ケース4:フィールドタイプの最適化
データベースシステムでは、異なるタイプのデータを処理する複雑さは大きく異なります。例えば、可変長タイプの処理は固定長タイプよりもはるかに複雑で、同様に高精度タイプの処理は低精度タイプよりも複雑です。
この特性は、ビジネスシステムSchemaの設計と後の最適化において重要な洞察を提供します:
- ビジネスシステムの表現と計算のニーズを満たしながら、固定長タイプを優先し、可変長タイプの使用を避けるべきです;
- 同時に、高精度タイプではなく低精度タイプを採用すべきです。具体的な実践には、VARCHARやSTRINGタイプフィールドをBIGINTで置き換えることや、DECIMALタイプフィールドをFLOAT / INT / BIGINTで置き換えることが含まれます。このようなフィールドタイプの合理的な設計と最適化は、ビジネス計算効率を大幅に向上させ、それによってシステムパフォーマンスを改善します。
Schemaタイプを定義する際は、固定長および低精度タイプを優先する原則に従ってください。
まとめ
要約すると、適切に設計されたSchemaはDorisの機能の利用を最大化し、それによってビジネスパフォーマンスを大幅に向上させることができます。逆に、最適化されていないSchema設計は、データスキューの原因となるなど、ビジネスに全体的な悪影響を与える可能性があります。したがって、初期のSchema設計最適化作業は特に重要です。