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

Sort keys and prefix indexes

ソートキーとプレフィックスインデックス

テーブルを作成する際に、その一つまたは複数の列をソートキーとして選択することができます。ソートキーは、データがディスクに格納される前にテーブルのデータを並べ替える順序を決定します。クエリのフィルタ条件としてソートキー列を使用することができます。そのため、StarRocksは必要なデータを高速に検索して処理するため、テーブル全体をスキャンして必要なデータを見つける必要がありません。これにより、検索の複雑さが低減され、クエリの処理が加速されます。

さらに、メモリ使用量を削減するために、StarRocksはテーブルにプレフィックスインデックスを作成することもサポートしています。プレフィックスインデックスはスパースインデックスの一種です。StarRocksはテーブルの各ブロックごとに1024行を格納し、そのブロックに関するインデックスエントリをプレフィックスインデックステーブルに生成して格納します。ブロックのプレフィックスインデックスエントリの長さは36バイトを超えることはできず、その内容はそのブロックの最初の行のテーブルのソートキー列のプレフィックスです。これにより、プレフィックスインデックステーブルの検索の実行時に、その行のデータを格納しているブロックの開始列番号をStarRocksが素早く見つけることができます。テーブルのプレフィックスインデックスは、テーブル自体のサイズの1024分の1となります。そのため、プレフィックスインデックス全体をメモリにキャッシュし、クエリの処理を高速化するのに役立ちます。

原則

"Duplicate Key"テーブルでは、ソートキー列は「DUPLICATE KEY」というキーワードを使用して定義します。

"Aggregate Key"テーブルでは、ソートキー列は「AGGREGATE KEY」というキーワードを使用して定義します。

"Unique Key"テーブルでは、ソートキー列は「UNIQUE KEY」というキーワードを使用して定義します。

v3.0以降、Primary Keyテーブルでは、Primary Key列とソートキー列が分離されます。ソートキー列は「ORDER BY」というキーワードを使用して定義します。Primary Key列は「PRIMARY KEY」というキーワードを使用して定義します。

Duplicate Keyテーブル、Aggregate Keyテーブル、またはUnique Keyテーブルのソートキー列を定義する際には、次の点に注意してください:

  • ソートキー列は、連続して定義される列であり、最初に定義された列が開始ソートキー列である必要があります。
  • ソートキー列として選択する予定の列は、他の共通の列よりも前に定義されている必要があります。
  • ソートキー列をリストする順序は、テーブルの列を定義する順序に準拠する必要があります。

4つの列、「site_id」、「city_code」、「user_id」、「pv」から構成されるテーブルのソートキー列の許容される例と許容されない例を以下に示します。

  • 許容されるソートキー列の例:
    • 「site_id」と「city_code」
    • 「site_id」、「city_code」と「user_id」
  • 許容されないソートキー列の例:
    • 「city_code」と「site_id」
    • 「city_code」と「user_id」
    • 「site_id」、「city_code」と「pv」

以下のセクションでは、さまざまなタイプのテーブルを作成する際に、ソートキー列をどのように定義するかの例を提供します。これらの例は、少なくとも3つのBE(バックエンド)を持つStarRocksクラスタに適しています。

Duplicate Key

site_access_duplicateという名前のテーブルを作成します。このテーブルは4つの列、「site_id」、「city_code」、「user_id」、「pv」から構成されており、そのうち「site_id」と「city_code」をソートキー列として選択します。

テーブルを作成するための文は以下の通りです:

CREATE TABLE site_access_duplicate
(
site_id INT DEFAULT '10',
city_code SMALLINT,
user_id INT,
pv BIGINT DEFAULT '0'
)
DUPLICATE KEY(site_id, city_code)
DISTRIBUTED BY HASH(site_id);

注意

v2.5.7以降、StarRocksはテーブルを作成するかパーティションを追加する際に、バケット数(BUCKETS)を自動的に設定することができます。バケット数を手動で設定する必要はもはやありません。詳細については、バケット数の決定を参照してください。

Aggregate Key

site_access_aggregateという名前のテーブルを作成します。このテーブルは4つの列、「site_id」、「city_code」、「user_id」、「pv」から構成されており、そのうち「site_id」と「city_code」をソートキー列として選択します。

テーブルを作成するための文は以下の通りです:

CREATE TABLE site_access_aggregate
(
site_id INT DEFAULT '10',
city_code SMALLINT,
user_id BITMAP BITMAP_UNION,
pv BIGINT SUM DEFAULT '0'
)
AGGREGATE KEY(site_id, city_code)
DISTRIBUTED BY HASH(site_id);

注意

Aggregateテーブルでは、agg_typeが指定されていない列はキーカラムであり、agg_typeが指定されている列は値カラムです。CREATE TABLEを参照してください。上記の例では、「site_id」と「city_code」のみがソートキー列として指定されているため、user_idpvにはagg_typeを指定する必要があります。

Unique Key

site_access_uniqueという名前のテーブルを作成します。このテーブルは4つの列、「site_id」、「city_code」、「user_id」、「pv」から構成されており、そのうち「site_id」と「city_code」をソートキー列として選択します。

テーブルを作成するための文は以下の通りです:

CREATE TABLE site_access_unique
(
site_id INT DEFAULT '10',
city_code SMALLINT,
user_id INT,
pv BIGINT DEFAULT '0'
)
UNIQUE KEY(site_id, city_code)
DISTRIBUTED BY HASH(site_id);

Primary Key

site_access_primaryという名前のテーブルを作成します。このテーブルは4つの列、「site_id」、「city_code」、「user_id」、「pv」から構成されており、そのうち「site_id」が主キー列、「site_id」と「city_code」がソートキー列として選択されます。

テーブルを作成するための文は以下の通りです:

CREATE TABLE site_access_primary
(
site_id INT DEFAULT '10',
city_code SMALLINT,
user_id INT,
pv BIGINT DEFAULT '0'
)
PRIMARY KEY(site_id)
DISTRIBUTED BY HASH(site_id)
ORDER BY(site_id,city_code);

ソート効果

前述のテーブルを使用して、次の3つの状況でソート効果が異なります。

  • クエリにおいて「site_id」と「city_code」の両方でフィルタリングを行う場合、クエリ実行時にスキャンする行数が大幅に減少します:

    select sum(pv) from site_access_duplicate where site_id = 123 and city_code = 2;
  • クエリにおいて「site_id」だけをフィルタリングする場合、StarRocksは「site_id」の値を含む行にクエリ範囲を絞り込むことができます:

    select sum(pv) from site_access_duplicate where site_id = 123;
  • クエリにおいて「city_code」だけをフィルタリングする場合、StarRocksはテーブル全体をスキャンする必要があります:

    select sum(pv) from site_access_duplicate where city_code = 2;

    注意

    この状況では、ソートキー列は期待するソート効果を生み出しません。

上記のように、「site_id」と「city_code」の両方でクエリのフィルタリングを行う場合、StarRocksはクエリ範囲を特定の位置に絞り込むためにテーブル上でバイナリ検索を実行します。テーブルに多数の行が含まれている場合、StarRocksは「site_id」と「city_code」の列上でバイナリ検索を実行する必要があります。これにより、「site_id」と「city_code」のデータをメモリに読み込む必要が生じ、メモリの消費量が増加します。このような場合、プレフィックスインデックスを使用してメモリにキャッシュするデータ量を減らすことで、クエリの処理を高速化することができます。

また、多数のソートキー列もメモリ消費量を増加させます。StarRocksは以下の制限をプレフィックスインデックスの使用に課しています:

  • ブロックのプレフィックスインデックスエントリは、そのブロックの最初の行のテーブルのソートキー列のプレフィックスでなければなりません。
  • プレフィックスインデックスは最大3つの列に作成することができます。
  • プレフィックスインデックスエントリの長さは36バイトを超えることはできません。
  • プレフィックスインデックスはFLOATまたはDOUBLEデータ型の列に作成することはできません。
  • プレフィックスインデックスが作成される列の中で、VARCHARデータ型の列は1つだけ許可されており、その列はプレフィックスインデックスの終端列である必要があります。
  • プレフィックスインデックスの終端列がCHARまたはVARCHARデータ型の場合、プレフィックスインデックスのエントリは36バイトを超えることはできません。

ソートキー列の選択方法

このセクションでは、「site_access_duplicate」テーブルを例に、ソートキー列の選択方法について説明します。

  • よくフィルタリングされる列を特定し、これらの列をソートキー列として選択することを推奨します。
  • 複数のソートキー列を選択する場合、高い識別レベルを持つ頻繁にフィルタリングされる列を他の列よりも先にリストすることを推奨します。列の識別レベルは、その列の値の数が多く、連続して増加する場合に高いです。例えば、「site_access_duplicate」テーブルの都市の数は固定されており、つまり「city_code」列の値の数も固定されています。しかし、「site_id」の値の数は「city_code」の値の数よりもはるかに多く、かつ連続的に増加しています。したがって、「site_id」列の識別レベルは「city_code」列よりも高いです。
  • 多数のソートキー列を選択しないことを推奨します。多数のソートキー列はクエリのパフォーマンス向上に役立つことはありませんが、ソートやデータのロードに関連するオーバーヘッドを増加させます。

まとめると、site_access_duplicateテーブルのソートキー列を選択する際には、以下の点に注意してください。

  • クエリで「site_id」と「city_code」の両方のフィルタリングが頻繁に行われる場合、開始ソートキー列として「site_id」を選択することをおすすめします。
  • クエリでフィルタリングするのが主に「city_code」であり、時折「site_id」と「city_code」の両方をフィルタリングする場合、開始ソートキー列として「city_code」を選択することをおすすめします。
  • クエリで「site_id」と「city_code」の両方のフィルタリング回数が「city_code」のみのフィルタリング回数とほぼ同じである場合、最初の列が「city_code」のマテリアライズドビューを作成することをおすすめします。これにより、StarRocksはマテリアライズドビューの「city_code」列にソートインデックスを作成します。