검색 최적화로 지리공간 쿼리 속도 향상

검색 최적화로 지리공간 쿼리 속도 향상

검색 최적화 서비스는 GEOGRAPHY 객체와 함께 지리공간 함수를 사용하는 조건부가 있는 쿼리의 성능을 향상시킬 수 있습니다.

다음 섹션은 지리공간 쿼리에 대한 검색 최적화 지원에 대한 자세한 정보를 제공합니다.

참고

GEOMETRY 객체는 아직 지원되지 않습니다.

출처: Snowflake 문서

본문

지리공간 쿼리에 대한 검색 최적화 활성화

테이블에서 지리공간 쿼리의 성능을 향상시키려면 특정 열에 대해 ALTER TABLE … ADD SEARCH OPTIMIZATION 명령의 ON GEO 절 을 사용하세요. 테이블 수준에서 검색 최적화를 활성화해도 지리공간 데이터 타입이 있는 열에서는 활성화되지 않습니다.

예를 들어:

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

자세한 내용은 검색 최적화 활성화 및 비활성화 를 참고하세요.

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

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

다음과 같은 경우 검색 최적화 서비스가 성능을 향상시킬 수 있습니다.

  • 한 입력 표현식이 테이블의 GEOGRAPHY 열이고,
  • 다른 입력 표현식이 GEOGRAPHY 상수(변환 또는 생성자 함수 를 통해 생성)인 경우.
  • ST_DWITHIN의 경우, 거리 인자가 음수가 아닌 REAL 상수입니다.

이 기능은 검색 최적화 서비스에 적용되는 동일한 제한 사항 이 있습니다.

기타 성능 고려 사항

검색 최적화 서비스는 선택도(selectivity)가 높은 조건부를 위해 설계되었고 조건부가 지리공간 객체 간의 근접도로 필터링하기 때문에, 테이블에서 지리공간 객체를 근접도로 클러스터링하면 더 나은 성능을 얻을 수 있습니다. 기본 테이블이 자주 변경되는지 여부에 따라, 데이터 로드 시 정렬 순서를 지정하거나 Automatic Clustering을 사용해 데이터를 클러스터링할 수 있습니다.

  • 사전 정렬된 데이터 로드: 기본 테이블의 데이터가 자주 변경되지 않는다면 데이터 로드 시 정렬 순서를 지정할 수 있습니다. 그런 다음 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);

기본 데이터에 큰 변경이 있을 때마다 데이터를 수동으로 다시 정렬할 수 있습니다.

자동 클러스터링

기본 테이블에 빈번한 업데이트가 있다면 ALTER TABLE … CLUSTER BY … 명령을 사용해 Automatic Clustering 을 활성화해 테이블이 변경됨에 따라 자동으로 재클러스터링되게 할 수 있습니다.

다음 예시는 VARCHAR 타입의 새 열 geom_geohash를 추가하고 GEOGRAPHY 열 geom의 geohash 또는 H3 인덱스를 그 새 열에 저장합니다. 그런 다음 새 열을 클러스터 키로 사용해 Automatic Clustering을 활성화합니다. 이 접근 방식은 테이블에서 변경되는 부분만 자동으로 재클러스터링합니다.

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);

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

다음 문은 이 섹션의 예시에서 사용되는 테이블을 생성하고 구성합니다. 마지막 문은 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);

지원되는 조건부 예시

다음 쿼리는 검색 최적화 서비스에서 지원되는 쿼리의 예시입니다. 검색 최적화 서비스는 검색 액세스 경로를 사용해 이 쿼리의 성능을 향상시킬 수 있습니다.

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

다음은 검색 최적화 서비스에서 지원되는 추가 조건부의 예시입니다.

...
  ST_INTERSECTS(
    TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
    g1)
...
  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)
...
  ST_CONTAINS(
    g1,
    TO_GEOGRAPHY('MULTIPOINT((0 0), (1 1))'))
...
  ST_WITHIN(
   TO_GEOGRAPHY('{"type" : "MultiPoint","coordinates" : [[-122.30, 37.55], [-122.20, 47.61]]}'),
   g1)
...
  ST_WITHIN(
    g1,
    TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'))
...
  ST_COVERS(
    TO_GEOGRAPHY('POLYGON((-1 -1, -1 4, 4 4, 4 -1, -1 -1))'),
    g1)
...
  ST_COVERS(
    g1,
    TO_GEOGRAPHY('POINT(0 0)'))
...
  ST_COVEREDBY(
    TO_GEOGRAPHY('POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))'),
    g1)
...
  ST_COVEREDBY(
    g1,
    TO_GEOGRAPHY('POINT(-122.35 37.55)'))
...
  ST_DWITHIN(
    TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
    g1,
    100000)
...
  ST_DWITHIN(
    g1,
    TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
    100000)

GEOGRAPHY 상수 구성 예시

다음은 GEOGRAPHY 상수에 대해 다양한 변환 및 생성자 함수 를 사용하는 조건부의 예시입니다.

...
  ST_INTERSECTS(
    g1,
    ST_GEOGRAPHYFROMWKT('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'))
...
  ST_INTERSECTS(
    ST_GEOGFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
    g1)
...
  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)
...
  ST_WITHIN(
    ST_GEOGRAPHYFROMWKB('01010000006666666666965EC06666666666C64240'),
    g1)
...
  ST_COVERS(
    g1,
    ST_MAKEPOINT(0.2, 0.8))
...
  ST_INTERSECTS(
    g1,
    ST_MAKELINE(
      TO_GEOGRAPHY('MULTIPOINT((0 0), (1 1))'),
      TO_GEOGRAPHY('POINT(0.8 0.2)')))
...
  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)
...
  ST_WITHIN(
    g1,
    TRY_TO_GEOGRAPHY('POLYGON((-1 -1, -1 4, 4 4, 4 -1, -1 -1))'))
...
  ST_COVERS(
    g1,
    ST_GEOGPOINTFROMGEOHASH('s00'))

더 알아보기 (Learn more)