メインコンテンツまでスキップ
バージョン: 4.x

テーブルスキーマ設計の最適化

概要

Schema設計とチューニングにおいて、テーブルSchema設計は重要な部分であり、テーブルエンジンの選択、パーティションとバケット列の選択、パーティションとバケットサイズの設定、キー列とフィールドタイプの最適化などが含まれます。適切なSchema設計を欠くシステムでは、データスキューなどの問題が発生し、システムの並列処理とソート機能を十分に活用できず、ビジネスシステム内でDorisシステムが真のパフォーマンス優位性を実現することが妨げられる可能性があります。

詳細な設計原則については、Data Table Designセクションで詳細情報を参照できます。本章では、実用的なケースの観点から、いくつかの典型的なシナリオにおいてSchema設計の問題によって引き起こされるパフォーマンスのボトルネックを紹介し、ビジネスチューニングの参考のための最適化提案を提供します。

ケース1: テーブルエンジンの選択

DorisはDuplicate、Unique、Aggregateの3つのテーブルモデルをサポートしています。その中でも、UniqueはMerge-On-Read (MOR)とMerge-On-Write (MOW)にさらに分類できます。

これらのテーブルモデルのクエリパフォーマンスは、優秀な順に: Duplicate > MOW > MOR == Aggregateとなります。そのため、通常の状況では、特別な要件がない場合、より良いクエリパフォーマンスのためにDuplicateテーブルが推奨されます。

ヒント

ビジネスにデータ更新要件がなく、クエリパフォーマンスに対する要求が高い場合は、Duplicateテーブルが推奨されます。

ケース2: バケット列の選択

Dorisはデータのバケット化をサポートしており、これはSchema内のバケットキーに基づいてデータを分散し、データバケットを形成することを意味します。

適切なバケット列の選択は、生データの合理的な分散にとって重要であり、データスキューによって引き起こされるパフォーマンス問題を効果的に防止します。同時に、DorisのColocate JoinとBucket Shuffle Join機能の活用を最大化し、Join操作のパフォーマンスを大幅に向上させます。

テーブルt1のテーブル作成文を例にとると、現在のバケット列は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や特定の値など、大量のskewed値を含む可能性があることが事前に分かっている場合、これらのフィールドはbucket列として避けるべきです。逆に、user IDなど、ビジネス上の意味で適切なハッシュ特性を持つフィールドをbucket列として選択すべきです。パフォーマンス問題のトラブルシューティングフェーズでは、以下のSQL文を使用してbucketフィールドにデータskewがあるかどうかを確認し、それに応じて後続の最適化調整を行うことができます。

select c2,count(*) cnt from t1 group by c2 order by cnt desc limit 10;
ヒント

bucket列にデータスキューの問題があるかどうかを確認してください。ある場合は、ビジネス上の意味で適切なハッシュ特性を持つフィールドをbucket列として置き換えてください。

適切な事前設計により、問題が発生した際の特定と修正のコストを大幅に削減できることは明らかです。そのため、不要なコストの発生を避けるために、ビジネス担当者がSchema設計フェーズで厳密な設計とチェックを実施することを強く推奨します。

Case 3: Key Column最適化

3つのテーブルモデルのうち、テーブル作成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);

上記のビジネス要件とテーブルt1のスキーマ設計および後の最適化において、クエリプロセスを高速化するためにカラム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の設計と後の最適化に重要な洞察を提供します:

  1. ビジネスシステムの表現と計算のニーズを満たしながら、固定長タイプを優先し、可変長タイプの使用を避けるべきです;
  2. 同時に、高精度タイプではなく低精度タイプを採用すべきです。具体的な実践には、VARCHARやSTRINGタイプフィールドを置き換えるためのBIGINTの使用、DECIMALタイプフィールドを置き換えるためのFLOAT / INT / BIGINTの使用が含まれます。このようなフィールドタイプの合理的な設計と最適化は、ビジネス計算効率を大幅に向上させ、それによりシステムパフォーマンスを改善します。
ヒント

Schemaタイプを定義する際は、固定長および低精度タイプを優先する原則に従ってください。

まとめ

要約すると、適切に設計されたSchemaはDorisの機能の活用を最大化し、それによりビジネスパフォーマンスを大幅に向上させることができます。逆に、最適化されていないSchema設計は、データスキューを引き起こすなど、ビジネスに全体的な悪影響を与える可能性があります。したがって、初期のSchema設計最適化作業は特に重要です。