このトピックでは、グローバルセカンダリインデックス (GSI) の原則、機能、およびタイプについて説明します。
概要
GSIはPolarDB-Xの重要な機能です。 ローカルセカンダリインデックスと比較して、GSIのデータは、指定されたパーティショニングルールに基づいてデータノードに分散されます。 GSIを使用すると、プライマリキーとは異なるメソッドでデータをクエリし、データセット全体に一意の制約を適用できます。
原則と特徴
分散データベースのパーティションテーブルでは、テーブルの作成時に指定されたパーティションキーに基づいてデータが整理され、格納されます。 したがって、パーティションキーに基づくクエリは、関連するパーティションにすばやくルーティングできます。 パーティションキーを使用しないクエリには、完全なパーティションスキャンが必要です。 分散データベースでは、フルパーティションスキャンは、低速クエリの数を増加させ、システムスループットを低下させ、システムに線形スケーリング機能を失わせる可能性があります。 最適なパフォーマンスを維持するために、すべてのパーティションがスキャンされないように対策を実装することを推奨します。
パーティションキーを含むクエリは、特定のパーティションに向けられます。 N個のデータノードを有するシステムでは、単一ノード上のクエリの平均負荷は、クエリ負荷の1/Nです。 クエリにパーティションキーが含まれていない場合は、すべてのパーティションにわたるフルスキャンがトリガーされます。 各データノードに対する単一のクエリの平均負荷は1になります。 単一のデータノードのパフォーマンスの上限は、分散データベースのパフォーマンスの上限を決定します。 その結果、システムは線形スケーリング能力を失います。
PolarDB-Xは、上記の問題に対処するためのGSI機能を提供します。 PolarDB-Xでは、GSIを特別なパーティションテーブルとして使用できます。これにより、プライマリテーブルの特定の列のデータが複製されます。 通常のパーティション分割テーブルと同様に、GSIは、ユーザー定義のパーティション分割ルールに基づいていくつかのパーティションに水平に分割され、パーティションは異なるデータノードに分散されます。 クエリにプライマリテーブルのパーティションキーが含まれていないが、GSIのパーティションキーが含まれている場合、PolarDB-Xは最初にGSIの関連パーティションからデータを取得し、次にプライマリテーブルにアクセスして追加の関連情報を取得します。 これにより、すべてのパーティションにわたるフルスキャンが防止されます。
PolarDB-Xは分散トランザクションを使用して、プライマリテーブルとGSIの間で強力なデータ一貫性を維持します。
GSIはまた次の特徴を支えます:
テーブルをロックすることなく、GSIを変更、作成、および削除できます。
カスタムカバー列を指定して、プライマリテーブルでのルックアップ操作のオーバーヘッドを減らすことができます。
見えないインデックスがサポートされています。
タイプ
GSI
GSIは、プライマリテーブルとは異なるパーティショニング方法を提供できます。 SQL文のクエリ条件にプライマリテーブルのパーティションキーが含まれていないが、GSIのパーティションキーが含まれている場合、クエリはすべてのパーティションをスキャンしません。
たとえば、user_id列とname列に基づいてuser_tblテーブルを照会する場合は、g_i_nameという名前のGSIを作成できます。 これにより、name列に基づいてテーブルをクエリするときに、すべてのパーティションがスキャンされなくなります。
CREATE TABLE user(
user_id bigint,
name varchar(10),
addr varchar(30),
GLOBAL INDEX `g_i_name` (name) PARTITION BY HASH(name),
PRIMARY KEY(user_id)
) PARTITION BY KEY(user_id);
UGSI
一意のグローバルセカンダリインデックス (UGSI) は、通常のGSIのプロパティを持ち、グローバルunique制約を実装する特別なGSIです。
たとえば、ユーザーの携帯電話番号をuser2テーブルでグローバルに一意にしたい場合は、電話フィールドにUGSIをインデックスキーとして作成できます。
CREATE TABLE user2(
user_id bigint,
phone varchar(20),
addr varchar(30),
UNIQUE GLOBAL INDEX `g_i_phone`(phone) PARTITION BY HASH(phone),
PRIMARY KEY(user_id)
) PARTITION BY KEY(user_id);
クラスタ化されたGSI
クラスター化されたグローバルセカンダリインデックス (クラスター化されたGSI) は特別なGSIです。 既定では、クラスター化されたGSIには、プライマリテーブルのすべての列のデータが含まれます。 クラスタ化されたGSIによって占有されるディスク容量は、プライマリテーブルによって占有されるディスク容量に等しい。 クラスタ化されたGSIを使用して、すべてのパーティションがスキャンされ、ルックアップ操作のオーバーヘッドを防ぐことができます。
たとえば、user_id列またはorder_id列に基づいてorder_tblテーブルをクエリし、user_id列に基づいて注文をクエリするときにテーブルのルックアップ操作を防止する場合は、インデックスキーとしてuser_id列にcg_i_userという名前のクラスタ化GSIを作成できます。 user_id列に基づいて注文をクエリすると、PolarDB-Xはクエリをcg_i_userの特定のパーティションにルーティングします。 cg_i_userにはプライマリテーブルのすべてのデータが含まれているため、PolarDB-Xはプライマリテーブルを検索する必要はありません。
CREATE TABLE order_tbl(
order_id bigint,
user_id bigint,
addr varchar(30),
info text,
create_time datetime,
CLUSTERED INDEX `cg_i_user`(user_id) PARTITION BY HASH(user_id),
PRIMARY KEY(order_id)
) PARTITION BY KEY(order_id);
パフォーマンス
GSIが読み書きパフォーマンスに与える影響は、ビジネスシナリオによって異なります。 ほとんどの場合、GSIは書き込みパフォーマンスを低下させ、読み取りパフォーマンスを大幅に向上させます。 以下の例では、Sysbenchシナリオを使用して、GSIが読み書きのスループットに与える影響を示します。
読み取りパフォーマンス
Table | スレッド | Sysbench seIect_random_rangesシナリオ | Sysbench seIect_random_pointsシナリオ | ||||
QPS | 平均レイテンシ | 95% レイテンシ | QPS | 平均レイテンシ | 95% レイテンシ | ||
パーティションテーブル | 128 | 2769.17 | 46.21 | 99.33 | 5226.99 | 24.48 | 42.61 |
256 | 3415.64 | 144.97 | 144.97 | 5476.76 | 46.73 | 82.96 | |
512 | 3272.46 | 156.31 | 257.95 | 5290.67 | 96.72 | 179.94 | |
1024 | 2453.16 | 416.12 | 539.71 | 5165.31 | 198.07 | 404.61 | |
パーティションテーブル + GSI | 128 | 9662.11 | 13.24 | 25.28 | 22584.89 | 5.66 | 9.73 |
256 | 10431.73 | 24.52 | 51.02 | 25558.26 | 10.01 | 17.95 | |
512 | 15634.51 | 32.72 | 73.13 | 27116.56 | 18.86 | 39.65 | |
1024 | 229448.76 | 44.53 | 108.68 | 32509.87 | 31.43 | 73.13 |
GSIが作成された後:
範囲クエリでは、QPSが3415.64から22948.76に増加します。これは、範囲クエリのパフォーマンスが571% によって改善されます。
ポイントクエリでは、QPSが5476から32509.87に増加します。これは、ポイントクエリのパフォーマンスが493% によって改善されます。
結論: GSIは、インデックス列でのSysbenchのクエリパフォーマンスを向上させることができます。
データ書き込みパフォーマンス
Table | スレッド | Sysbench seIect_random_rangesシナリオ | Sysbench seIect_random_pointsシナリオ | ||||
QPS | 平均レイテンシ | 95% レイテンシ | QPS | 平均レイテンシ | 95% レイテンシ | ||
パーティションテーブル | 128 | 86548.12 | 8.87 | 10.27 | 113655.28 | 22.52 | 26.2 |
256 | 115774.71 | 13.26 | 19.29 | 149677.52 | 34.19 | 44.17 | |
512 | 143928.94 | 20.51 | 34.95 | 14555.16 | 70.28 | 112.67 | |
1024 | 153501.7 | 39.53 | 70.55 | 132150.69 | 131.58 | 287.38 | |
パーティションテーブル + GSI | 128 | 52069.22 | 14.25 | 18.28 | 90074.59 | 28.41 | 33.72 |
256 | 66250.79 | 23.17 | 32.53 | 114420.32 | 44.73 | 57.87 | |
512 | 75700.74 | 39.1 | 59.99 | 111093.61 | 92.09 | 142.39 | |
1024 | 76557.94 | 80.14 | 134.9 | 101828.32 | 182.51 | 350.33 |
GSIが作成された後:
書き込み専用動作では、QPSは153501.7から76557.94に減少し、これは、書き込みQPSが50% 減少したことを示します。
読み取りおよび書き込み動作では、QPSは149677.52から114420.32に減少し、これは、書き込みおよび読み取りQPSが23% 減少することを示します。
結論: GSIが作成されると、Sysbenchの書き込みパフォーマンスが低下します。