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

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

概要

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

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

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

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

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

ヒント

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

Case 2: バケットカラムの選択

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

適切なバケットカラムの選択は、生データの合理的な分散にとって不可欠であり、データスキューによって引き起こされるパフォーマンス問題を効果的に防ぎます。同時に、DorisのColocate Joinとバケット 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や特定の値など大量の偏った値を含む可能性があることが事前に分かっている場合、これらのフィールドは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つのテーブルモデルのうち、テーブル作成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の設計とテーブル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設計最適化作業は特に重要です。