Tableスキーマ設計の最適化
概要
Schema設計とチューニングにおいて、TableSchema設計は重要な部分であり、Tableエンジンの選択、パーティションとバケットカラムの選択、パーティションとバケットサイズの設定、キーカラムとフィールドタイプの最適化などが含まれます。適切なSchema設計を欠くシステムでは、データスキュー、システムの並列性とソート機能を十分に活用できない等の問題が発生し、DorisシステムがビジネスシステムにおいてTRUEのパフォーマンス優位性を実現することを阻害する可能性があります。
詳細な設計原則については、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);
上記のビジネス要件とTablet1のSchema設計および後続の最適化において、クエリプロセスを高速化するためにカラム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設計最適化作業は特に重要です。