時空間クエリの性能を向上させるには、クエリ条件が指定された時空間インデックスと一致することを確認してください。これにより、Lindorm がテーブル内のすべてのデータをスキャンする必要がなくなります。このトピックでは、時空間クエリの性能を最適化する方法について説明します。
時空間条件のみを含むクエリの最適化
クエリの条件に空間範囲のみ、または空間範囲と時間範囲のみが含まれている場合は、Z-ORDER
インデックス関数を使用して、空間列または時間列の時空間コードを次のいずれかの形式で生成できます。Z-ORDER(geometry)
または Z-ORDER(geometry,time)
。クエリで Z-ORDER 関数を使用する場合は、次の点に注意してください。
Z-ORDER
関数に指定する入力パラメーターは、クエリの性能に影響します。Z-ORDER
関数の入力パラメーターとして指定したすべての列がクエリ条件に含まれている場合にのみ、時空間インデックスを使用できます。Z-ORDER
関数を使用して空間列と時間列の両方に対して時空間コードを生成する場合、時間範囲の上限と下限の両方がクエリ条件に指定されている場合にのみ、時空間インデックスを使用できます。
次の表は、Z-ORDER
インデックス関数に異なる入力パラメーターを指定した場合のクエリ性能への影響について説明しています。表に記載されているサンプル文では、g 列は空間列、t 列は時間列です。
条件 | 文 |
|
|
空間範囲のみが指定されている。 |
|
|
|
空間範囲と時間範囲の両方が指定されている。 |
|
|
|
|
| 時間範囲の下限が指定されていないため、 |
時空間条件とその他の条件を含むクエリの最適化
クエリ条件に時空間条件とその他の条件が含まれている場合は、クエリを高速化するために複合インデックスを作成することをお勧めします。複合インデックスとは、Z-ORDER
関数とその他の列が含まれる主キーインデックスまたはセカンダリインデックスです(例:PRIMARY KEY(Z-ORDER(g,t), id)
)。Z-ORDER
関数は、特定の列の値に対応する時空間コードの列を返すため、複合インデックスに列として含まれています。LindormTable の複合インデックスの詳細については、「Z-ORDER
セカンダリインデックスに基づいてクエリを最適化する」をご参照ください。
並列クエリの最適化
並列クエリを有効にすると、シャーディングを使用してクエリの並列性を高め、クエリのパフォーマンスを向上させることができます。
シャーディングとは、データをシャードに分割するために使用される手法です。時空間インデックスを作成するときにシャーディングを使用して、データをより多くのシャードに分散できます。また、シャーディングを使用して、空間的または時間的に隣接するデータをインデックステーブルの異なるリージョンに書き込むこともできます。この場合、データはデータベースストレージの異なるシャードに格納されます。
次の形式で Z-ORDER
インデックス関数を使用して、点を格納する列の時空間インデックスを作成し、シャードの数を指定できます。Z-ORDER(Point, numShards)
。numShards パラメーターは、インデックステーブルの異なるリージョンに書き込まれるデータ行の数を指定します。0 から numShards-1
までの範囲の一連のプレフィックスが、書き込まれる前にこれらのデータ行に順番に個別に追加されます。
次の例では、時空間インデックスを作成するときにシャーディングを使用する前と後のクエリのパフォーマンスを比較しています。
約 1 億 5000 万行の点データを格納するサンプルテーブル用に table_noshard という名前の時空間テーブルを作成し、numShards を指定しません。
CREATE TABLE table_noshard(id INT, g GEOMETRY(POINT), name VARCHAR, PRIMARY KEY(Z-ORDER(g)));
table_noshard に対して並列クエリを有効にします。
SELECT /*+_l_enable_parallel_(8)*/ id FROM table_noshard WHERE ST_Contains(ST_GeomFromText('POLYGON((...))'), g);
結果によると、2,058,894 行のデータが 10986 ms 以内に返されます。
シャーディング使用後のクエリ パフォーマンス
同じサンプルテーブル用に table_shard8 という名前の時空間テーブルを作成し、numShards を 8 に設定します。
CREATE TABLE table_shard8(id INT, g GEOMETRY(POINT), name VARCHAR, PRIMARY KEY(Z-ORDER(g, 8)));
table_shard8 に対して並列クエリを有効にします。
SELECT /*+_l_enable_parallel_(8)*/ id FROM table_shard8 WHERE ST_Contains(ST_GeomFromText('POLYGON((...))'), g);
結果によると、2,058,894 行のデータが 2501 ms 以内に返されます。
結果によると、numShards を構成した後、並列クエリの性能が大幅に向上しています。
不規則な範囲が指定されたクエリの最適化
時空間インデックスを作成した後、指定されたクエリ範囲の形状が、インデックスのフィルタリング範囲で指定された四角形の境界ボックスの形状と大きく異なる場合、インデックスはクエリのパフォーマンスをほとんど向上させることができません。次の図は例を示しています。
大量のデータに対してクエリを実行する場合は、/*+_l_enable_enhanced_filter_*/ ヒントを指定して、拡張インデックスフィルタリングを有効にすることができます。
たとえば、次の文を実行して、gtest
という名前のテーブルに対して拡張インデックスフィルタリングを有効にすることができます。この例では、g
列に対して時空間インデックスが作成され、POLYGON((...))
は不規則な形状の範囲を指定します。
SELECT /*+_l_enable_enhanced_filter_*/ id FROM gtest WHERE ST_Contains(ST_GeomFromText('POLYGON((...))'), g);
少量のデータに対してクエリを実行する場合は、拡張インデックスフィルタリングを使用する必要はありません。そのため、拡張インデックスフィルタリングはデフォルトで無効になっています。