검색 최적화로 지리 공간 쿼리 속도 높이기

검색 최적화 서비스는 GEOGRAPHY 오브젝트와 함께 지리 공간 함수를 사용하는 조건자로 쿼리의 성능을 개선할 수 있습니다.

참고

ALTER TABLE … ADD SEARCH OPTIMIZATION 명령에서 ON 절을 사용하여 특정 열에 대해 이 기능을 활성화해야 합니다. 예:

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

ON 절을 생략하면 지리 공간 함수를 사용하는 쿼리가 개선되지 않습니다.

다음 섹션에서 더 자세히 설명합니다.

참고

GEOMETRY 오브젝트는 아직 지원되지 않습니다.

지리 공간 함수와 함께 지원되는 조건자

다음 함수를 사용하는 조건자가 있는 쿼리의 경우:

다음과 같은 경우에 검색 최적화 서비스는 성능을 개선할 수 있습니다.

  • 한 입력식은 테이블의 GEOGRAPHY 열이며,

  • 다른 입력식은 (변환 또는 생성자 함수 를 통해 생성됨) 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 의 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

지리 공간 함수를 사용하는 예

다음 문을 실행하면 이 섹션의 예에 사용된 테이블을 만들고 구성할 수 있습니다. 마지막 문에서는 ALTER TABLE … ADD SEARCH OPTIMIZATION 명령에 ON 절을 사용하여 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