검색 최적화로 지리공간 쿼리 속도 향상
검색 최적화로 지리공간 쿼리 속도 향상
검색 최적화 서비스는 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'))