web-dev-qa-db-ja.com

Cassandra:パーティションキーの選択

非常に一般的に共有されている列の値(Countryなど)を複合主キーのパーティションキーとして使用するか、かなりユニークな列の値(Last_Nameなど)を使用する方がパフォーマンス面で優れているかは、私には決まっていません。 )。

インデックスに関する Cassandra 1.2のドキュメントを見る 私はこれを取得します:

"いつインデックスを使用するか:Cassandraの組み込みインデックスは、インデックス付きの値を含む多くの行を持つテーブルに最適です。に存在するよりユニークな値特定の列を使用すると、平均して、クエリを実行してインデックスを維持するためのオーバーヘッドが大きくなります。たとえば、10億人のユーザーを持つユーザーテーブルがあり、ユーザーが住んでいる状態でユーザーを検索するとします。 in。多くのユーザーが州の同じ列の値(CA、NY、TXなど)を共有します。これはインデックスの良い候補になります。 "

"インデックスを使用しない場合:インデックスを使用して、大量のレコードをクエリして少数の結果を取得しないでください。たとえば、次のような列にインデックスを作成した場合、には多くの異なる値があるため、フィールド間のクエリでは、非常に少ない結果を求める多くのシークが発生します。 10億人のユーザーを含むテーブルで、メールアドレス(通常、各ユーザーに固有の値) )状態ではなく、非常に非効率的である可能性があります。Cassandraを使用する代わりに、テーブルをインデックスの形式として手動で維持する方が効率的です。組み込みインデックス。一意のデータを含む列の場合、インデックス付きの列を持つテーブルへのクエリ量が適度であり、一定の負荷がかかっていない限り、インデックスを使用するとパフォーマンスが向上することがあります。」

CQLのSELECT の例を見て

複合主キーのクエリと結果のソート」、パーティションキーとして使用されているUUIDのようなものが表示されます... これは、使用することをお勧めしますかなりユニークなもの

enter image description here

23
andandandand

作成したドキュメントのインデックスは、セカンダリインデックスを参照しています。 cassandraがあります プライマリインデックスとセカンダリインデックスの違い があります。セカンダリインデックスの場合、非常に一意の値を持つことは確かに悪いことですが、これは、どのコンポーネントに焦点を当てているかによって異なります。主キーには、次のコンポーネントがあります。

PRIMARY KEY(パーティショニングキー、クラスタリングkey_1 ...クラスタリングkey_n)

パーティションキーは、異なるノード間でデータを分散するために使用されます。ノードのバランスをとる(つまり、各ノード間でデータを適切に分散する)場合は、パーティションキーをできるだけランダムにする必要があります。そのため、この例ではUUIDを使用しています。

クラスタリングキーが使用されます順序付け。これにより、特定のクラスタリングキーで列をクエリすることがより効率的になります。ここで、値が一意にならないようにし、一意の行が頻繁にある場合にパフォーマンスが低下するようにします。

cql docs は、何が起こっているのかをよく説明しています。

40
Lyuben Todorov

列ファミリーを指定してcql3を使用する場合:

CREATE TABLE table1 (
  a1 text,
  a2 text,
  b1 text,
  b2 text,
  c1 text,
  c2 text,
  PRIMARY KEY ( (a1, a2), b1, b2) )
);

主キーを定義する((a1、a2、...)、b1、b2、...)

これは以下を意味します:

a1、a2、...は、次の目的で行キーを作成するために使用されるフィールドです。

  • データの分割方法を決定する
  • 物理的に単一の行に格納されているものを決定する
  • 行キーまたはパーティションキーと呼ばれます

b1、b2、...は、次の目的で行キーをクラスター化するために使用される列ファミリーフィールドです。

  • 単一行内に論理セットを作成する
  • 範囲範囲などのより柔軟な検索スキームを許可する
  • 列キーまたはクラスターキーと呼ばれる

残りのすべてのフィールドは、列キーの可能なすべての組み合わせに対して効果的に多重化/複製されます。以下に、パーティションキーとクラスタリングキーを使用した複合キーの例を示します。

範囲クエリを使用する場合は、セカンダリインデックスを使用するか、(cql3から開始して)これらのフィールドをクラスタリングキーとして宣言できます。速度の観点から、それらをクラスタ化キーとして使用すると、単一の広い行が作成されます。次のような複数のクラスタリングキー値をフェッチするため、これは速度に影響します。

select * from accounts where Country>'Italy' and Country<'Spain'

8
natbusa

私はあなたが答えを得たと確信していますが、それでもなおこれはあなたがより良い理解のためにあなたを助けることができます。

CREATE TABLE table1 (
  a1 text,
  a2 text,
  b1 text,
  b2 text,
  c1 text,
  c2 text,
  PRIMARY KEY ( (a1, a2), b1, b2) )
);

ここでは、パーティションキーは(a1、a2)で、行キーはb1、b2です。

パーティションキーと行キーの組み合わせは、新しいレコードエントリごとに一意である必要があります。

上記の主キーは次のように定義できます。

Node< key, value>

Node<(a1a2), Map< b1b2, otherColumnValues>>

ご存じのとおりパーティションキーは、ノード間のデータ分散を担当します。

したがって、同じパーティションキーと異なる行キーを持つ100個のレコードをtable1に挿入するとします。同じノードの異なる列にデータを格納します。

論理的には、このように表現できます。

Node<(a1a2), Map< string1, otherColumnValues>, Map< string2, otherColumnValues> .... Map< string100, otherColumnValues>>

したがって、レコードは順次メモリに格納されます。

1
Aftab