インデックスはどのように格納され、更新されるか

DataStax Enterpriseがどのようにインデックスを格納し、分散させるかの簡単な説明。

セカンダリ・インデックスは、非プライマリ・キー・カラムに格納されたデータのテーブルをフィルターします。たとえば、プライマリ・キーとしてサイクリストの姓を使用してサイクリストの名前および年齢を格納するテーブルには、年齢のセカンダリ・インデックスが含まれており、年齢によるクエリーが可能です。非プライマリ・キー・カラムと一致するクエリーは、必ず、テーブルから取得したデータの連続したスライスとなるため、アンチパターンです。

テーブル行が姓に基づいて格納されている場合、テーブルは、異なるノードに格納された複数のパーティションに分散される可能性があります。特定の範囲の姓に基づいたクエリー(姓がMatthewsのすべてのサイクリストなど)は、テーブルから連続する行を取得しますが、年齢に基づくクエリー(28歳のすべてのサイクリストなど)では、すべてのノードを値に対してクエリーする必要があります。非プライマリ・キーには格納時のデータの順序指定の役割がないため、非プライマリ・キー・カラムの特定の値のクエリーで、すべてのパーティションがスキャンされることになります。すべてのパーティションをスキャンするのは、ひどい読み取りレイテンシーの原因になるため、許可されません。

セカンダリ・インデックスは、テーブルのカラムに対して作成されます。これらのインデックスは、隠されているテーブルの中の各ノードにローカルに格納され、バックグラウンド・プロセスで作成されます。特定のパーティション・キーに制限されないクエリーでセカンダリ・インデックスが使用される場合、このクエリーでは、すべてのノードがクエリーされるため、ひどい読み取りレイテンシーが発生します。このようなパラメーターを持つクエリーは、クエリー・オプションALLOW FILTERINGが使用される場合にのみ許可されます。このオプションは、実稼働環境には適していません。クエリーにパーティション・キー条件とセカンダリ・インデックス・カラム条件が両方とも含まれている場合は、クエリーを1つのノードのパーティションに対して直接実行できるため、クエリーが成功します。

ただしこの方法では、問題のないインデックスができる保証がないため、インデックスを使用すべき場合と使用すべきでない場合について把握しておいてください。上の例では、年齢のインデックスを使用できますが、効果的な解決策は、年齢順のマテリアライズド・ビューまたは追加のテーブルを作成することです。

リレーショナル・データベースと同様、インデックスを最新の状態に保つには処理時間とリソースが使用されるため、不要なインデックスは排除すべきです。カラムが更新されると、インデックスもこれに伴って更新されます。小さな行セットを繰り返し更新したときに古いカラム値がmemtableに残る場合、DataStax Enterpriseはこのように古くなったインデックス・エントリーを削除します。そうしないと、古くなったエントリーはコンパクションによってパージされるまでそこに残ります。コンパクションによるパージが行われる前に読み取りで古いインデックス・エントリーが見つかった場合は、読み取りスレッドによってこれが無効にされます。