検索最適化による地理空間クエリの高速化

検索最適化サービスにより、 GEOGRAPHY オブジェクトで地理空間関数を使用する述語を使用するクエリのパフォーマンスを向上させることができます。

注釈

ON 句を使用した ALTER TABLE ... ADD SEARCH OPTIMIZATION コマンドで特定の列に対してこの機能を有効にする必要があります。例:

ALTER TABLE mytable ADD SEARCH OPTIMIZATION ON GEO(mygeocol);
Copy

ON 句を省略した場合、地理空間関数を使用するクエリは改善されません。

次のセクションで詳細を説明します。

注釈

GEOMETRY オブジェクトはまだサポートされていません。

地理空間関数でサポートされている述語

次の関数を使用する述語を含むクエリの場合、

検索最適化サービスにより、次の場合にパフォーマンスを向上させることができます。

  • 1つの入力式がテーブルの GEOGRAPHY 列であり、

  • もう1つの入力式が GEOGRAPHY 定数(変換またはコンストラクター関数 を介して作成)。

  • ST_DWITHIN の場合、距離引数は負ではない REAL 定数。

この機能には、 検索最適化サービスと同様の制限が適用 されることに注意してください。

その他のパフォーマンスの考慮事項

検索最適化サービスは選択性の高い述語用に設計されており、述語は地理空間オブジェクト間の近接性によってフィルターされるため、テーブル内の近接性によって地理空間オブジェクトをクラスタリングすると、パフォーマンスが向上する可能性があります。ベーステーブルが頻繁に変更されるかどうかに応じて、データをロードするときに並べ替え順序を指定するか、自動クラスタリングを使用して、データをクラスタ化できます。

ソート済みデータのロード

ベーステーブルのデータが頻繁に変更されない場合は、データをロードするときに並べ替え順序を指定できます。その後、GEOGRAPHY 列で検索の最適化を有効にできます。例:

CREATE TABLE new_table AS SELECT * FROM source_table ORDER BY st_geohash(geom);
ALTER TABLE new_table ADD SEARCH OPTIMIZATION ON GEO(geom);
Copy

ベースデータに大きな変更を加えるたびに、手動でデータを並べ替えることができます。

自動クラスタリング

ベーステーブルが頻繁に更新される場合は、 ALTER TABLE ... CLUSTER BY ... コマンドを使用して 自動クラスタリング を有効にし、テーブルが変更されると自動的に再クラスタリングされるようにします。

次の例では、タイプ VARCHAR の新しい列 geom_geohash を追加し、その新しい列に GEOGRAPHY 列 geom のgeohashまたはH3インデックスを格納します。次に、新しい列をクラスタキーとして自動クラスタリングを有効にします。このアプローチは、変更されたテーブルの部分を自動的に再クラスター化します。

CREATE TABLE new_table AS SELECT *, ST_GEOHASH(geom) AS geom_geohash FROM source_table;
ALTER TABLE new_table CLUSTER BY (geom_geohash);
ALTER TABLE new_table ADD SEARCH OPTIMIZATION ON GEO(geom);
Copy

地理空間関数を使用する例

次のステートメントは、このセクションの例で使用されるテーブルを作成および構成します。最後のステートメントは、 ON 句を ALTER TABLE ... ADD SEARCH OPTIMIZATION コマンドで使用して、 g1 GEOGRAPHY 列の検索最適化を追加します。

CREATE OR REPLACE TABLE geospatial_table (id NUMBER, g1 GEOGRAPHY);
INSERT INTO geospatial_table VALUES
  (1, 'POINT(-122.35 37.55)'),
  (2, 'LINESTRING(-124.20 42.00, -120.01 41.99)'),
  (3, 'POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))');
ALTER TABLE geospatial_table ADD SEARCH OPTIMIZATION ON GEO(g1);
Copy

サポートされている述語の例

次のクエリは、検索最適化サービスでサポートされているクエリの例です。検索最適化サービスにより、検索アクセスパスを使用して、このクエリのパフォーマンスを向上させることができます。

SELECT id FROM geospatial_table WHERE
  ST_INTERSECTS(
    g1,
    TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'));
Copy

以下は、検索最適化サービスでサポートされている追加の述語の例です。

...
  ST_INTERSECTS(
    TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
    g1)
Copy
...
  ST_CONTAINS(
    TO_GEOGRAPHY('POLYGON((-74.17 40.64, -74.1796875 40.58, -74.09 40.58, -74.09 40.64, -74.17 40.64))'),
    g1)
Copy
...
  ST_CONTAINS(
    g1,
    TO_GEOGRAPHY('MULTIPOINT((0 0), (1 1))'))
Copy
...
  ST_WITHIN(
   TO_GEOGRAPHY('{"type" : "MultiPoint","coordinates" : [[-122.30, 37.55], [-122.20, 47.61]]}'),
   g1)
Copy
...
  ST_WITHIN(
    g1,
    TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'))
Copy
...
  ST_COVERS(
    TO_GEOGRAPHY('POLYGON((-1 -1, -1 4, 4 4, 4 -1, -1 -1))'),
    g1)
Copy
...
  ST_COVERS(
    g1,
    TO_GEOGRAPHY('POINT(0 0)'))
Copy
...
  ST_COVEREDBY(
    TO_GEOGRAPHY('POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))'),
    g1)
Copy
...
  ST_COVEREDBY(
    g1,
    TO_GEOGRAPHY('POINT(-122.35 37.55)'))
Copy
...
  ST_DWITHIN(
    TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
    g1,
    100000)
Copy
...
  ST_DWITHIN(
    g1,
    TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
    100000)
Copy

GEOGRAPHY 定数の作成例

以下は、 GEOGRAPHY 定数に対してさまざまな 変換関数およびコンストラクター関数 を使用する述語の例です。

...
  ST_INTERSECTS(
    g1,
    ST_GEOGRAPHYFROMWKT('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'))
Copy
...
  ST_INTERSECTS(
    ST_GEOGFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
    g1)
Copy
...
  ST_CONTAINS(
    ST_GEOGRAPHYFROMEWKT('POLYGON((-74.17 40.64, -74.1796875 40.58, -74.09 40.58, -74.09 40.64, -74.17 40.64))'),
    g1)
Copy
...
  ST_WITHIN(
    ST_GEOGRAPHYFROMWKB('01010000006666666666965EC06666666666C64240'),
    g1)
Copy
...
  ST_COVERS(
    g1,
    ST_MAKEPOINT(0.2, 0.8))
Copy
...
  ST_INTERSECTS(
    g1,
    ST_MAKELINE(
      TO_GEOGRAPHY('MULTIPOINT((0 0), (1 1))'),
      TO_GEOGRAPHY('POINT(0.8 0.2)')))
Copy
...
  ST_INTERSECTS(
    ST_POLYGON(
      TO_GEOGRAPHY('SRID=4326;LINESTRING(0.0 0.0, 1.0 0.0, 1.0 2.0, 0.0 2.0, 0.0 0.0)')),
    g1)
Copy
...
  ST_WITHIN(
    g1,
    TRY_TO_GEOGRAPHY('POLYGON((-1 -1, -1 4, 4 4, 4 -1, -1 -1))'))
Copy
...
  ST_COVERS(
    g1,
    ST_GEOGPOINTFROMGEOHASH('s00'))
Copy