GetRange API が指定範囲外のデータを返す場合は、プライマリキーの順序を変更するためのセカンダリインデックスを作成し、ベーステーブルではなくそのインデックスに対してクエリを実行します。
症状
コンソール、SDK、Tablestore 外部テーブル、または Tablestore Reader を使用して範囲クエリを実行すると、GetRange API が指定した範囲外の行を返します。
原因
クエリ条件が左端プレフィックス一致ルールに従っていません。
Tablestore は、テーブルスキーマで定義された順序でプライマリキー列に基づき、物理的に行をソートします。プライマリキー列に設定された範囲は、それより前のすべての列に正確な(範囲ではない)値が指定されている場合にのみ有効になります。いずれかの先行列に範囲が指定されている場合、後続の列に設定された範囲は無視されます。
左端プレフィックス一致ルール — 有効なものと無効なもの:
有効な例: 最初のプライマリキー列に正確な値を設定し、2 番目の列に範囲を設定すると、2 番目の列がその範囲内にある行のみが返されます。
無効な例: 最初のプライマリキー列に範囲を設定し、2 番目の列に範囲(または正確な値)を設定しても、2 番目の列の条件は無視されます。
たとえば、最初の列に対して beginPrimaryKey = INF_MIN および endPrimaryKey = INF_MAX を設定し、2 番目の列に対して beginPrimaryKey = 10 および endPrimaryKey = 10 を設定した場合、クエリは 2 番目の列が 10 である行だけでなく、テーブル内のすべての行を返します。最初の列の範囲が全キースペースをカバーしているため、2 番目の列の条件は効果を持ちません。
ソリューション
フィルターをかけたい列が先頭キーとなるようにプライマリキーの順序を変更するため、セカンダリインデックスを作成します。その後、ベーステーブルではなくセカンダリインデックスに対して直接クエリを実行します。これにより、テーブルスキーマを変更せずに効果的な範囲条件を適用できます。
ご利用のシナリオに合ったアプローチを選択してください。
コンソールまたは SDK による範囲クエリ — セカンダリインデックスを使用しない場合、テーブル全体をスキャンして不要な行を破棄する必要があります。セカンダリインデックスを使用する場合は、インデックスに対して直接範囲クエリを実行します。手順については、「コンソールからセカンダリインデックスを使用する」または「SDK でセカンダリインデックスを使用する」をご参照ください。
Tablestore 外部テーブルクエリ —
CREATE TABLE文のテーブル名をセカンダリインデックスの名前に設定します。これにより、外部テーブルクエリがインデックス経由でルーティングされ、範囲条件が正しく適用されます。詳細については、「Tablestore 外部テーブル」をご参照ください。Tablestore Reader によるデータ同期 — 同期スクリプト内のテーブル名をセカンダリインデックスの名前に設定します。これにより、同期タスクがインデックスからデータを読み取り、定義した範囲を正しく反映します。詳細については、「Tablestore (OTS) Reader の設定」をご参照ください。