거리와 최근접 이웃
주변에 무엇이 있는지 찾아봅니다
거리와 최근접 이웃은(는) CoddyKit의 무료 SQL Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
공간 거리란 무엇인가요?
지리 공간 데이터베이스에서 거리는 두 지리적 위치 사이의 측정된 간격입니다. PostGIS는 점, 선, 다각형 및 기타 기하 도형 유형 사이의 거리를 계산하는 강력한 함수를 제공합니다.
거리 쿼리를 이해하면 내 위치에서 가장 가까운 식당은 어디인가요? 또는 창고에서 5km 이내에 있는 고객은 누구인가요?와 같은 질문에 답할 수 있습니다.
ST_Distance 함수
ST_Distance(geom_a, geom_b)는 두 기하 도형 객체 사이의 최소 거리를 반환합니다. 기본적으로 일반 geometry 유형을 사용할 때 결과는 좌표 참조 시스템과 동일한 단위이며, EPSG:4326에서는 보통 도 단위입니다.
미터 단위로 의미 있는 결과를 얻으려면 geography 유형을 사용하거나 데이터를 재투영해야 합니다.
SELECT ST_Distance(
ST_MakePoint(28.9784, 41.0082)::geography,
ST_MakePoint(29.0100, 41.0200)::geography
) AS distance_meters;샘플 테이블 설정
지리 좌표를 포함한 간단한 장소 테이블을 만들어 보겠습니다. 모든 거리 계산이 자동으로 미터 단위로 반환되도록 geography 유형을 사용하므로 수동으로 투영할 필요가 없습니다.
이 테이블에는 도시의 카페를 저장하며, 각 행에는 카페 이름과 점으로 저장된 위치가 포함됩니다.
CREATE TABLE cafes (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
location GEOGRAPHY(Point, 4326)
);
INSERT INTO cafes (name, location) VALUES
('Cafe Alpha', ST_MakePoint(28.9784, 41.0082)::geography),
('Cafe Beta', ST_MakePoint(28.9900, 41.0150)::geography),
('Cafe Gamma', ST_MakePoint(29.0100, 41.0200)::geography),
('Cafe Delta', ST_MakePoint(28.9650, 40.9980)::geography),
('Cafe Epsilon', ST_MakePoint(29.0250, 41.0350)::geography);고정된 지점에서의 거리 찾기
위치 데이터가 있으면 모든 행에서 기준점까지의 거리를 계산할 수 있습니다. 여기서는 좌표 (28.9800, 41.0100)에 있는 사용자를 기준으로 각 카페까지의 거리를 계산합니다.
geography 유형을 사용했으므로 결과는 미터 단위입니다.
SELECT
name,
ROUND(
ST_Distance(
location,
ST_MakePoint(28.9800, 41.0100)::geography
)::NUMERIC
) AS distance_m
FROM cafes
ORDER BY distance_m;최근접 이웃 찾기
주어진 지점에서 가장 가까운 하나의 위치를 찾으려면 거리순으로 정렬한 다음 LIMIT 1을 사용해 행 하나만 가져오면 됩니다. 이것이 전형적인 최근접 이웃 쿼리입니다.
이 패턴은 위치 인식 애플리케이션에서 매우 흔히 사용됩니다. 가장 가까운 매장, 의사 또는 대중교통 정류장을 찾는 경우가 그 예입니다.
SELECT
name,
ROUND(
ST_Distance(
location,
ST_MakePoint(28.9800, 41.0100)::geography
)::NUMERIC
) AS distance_m
FROM cafes
ORDER BY location <-> ST_MakePoint(28.9800, 41.0100)::geography
LIMIT 1;최근접 이웃을 위한 <-> 연산자
PostGIS는 색인을 활용할 수 있는 <-> 연산자(KNN — 최근접 이웃 K개)를 제공합니다. ORDER BY 절에서 ST_Distance를 사용하는 것과 달리 <->는 GiST 공간 색인을 사용해 모든 행을 검색하는 작업을 피할 수 있습니다.
최근접 이웃을 효율적으로 찾아야 한다면 ORDER BY에서 항상 <->를 우선 사용하세요. 이를 지원하려면 다음과 같이 색인을 생성하세요.
CREATE INDEX ON cafes USING GIST (location);
SELECT
name,
ROUND(
ST_Distance(
location,
ST_MakePoint(28.9800, 41.0100)::geography
)::NUMERIC
) AS distance_m
FROM cafes
ORDER BY location <-> ST_MakePoint(28.9800, 41.0100)::geography
LIMIT 5;거리로 필터링하기(ST_DWithin)
ST_DWithin(geom_a, geom_b, distance)는 두 기하 도형이 지정된 거리 이내에 있으면 TRUE를 반환합니다. geography 유형에서는 거리가 미터 단위입니다.
WHERE 절에서 ST_Distance(...) < radius를 사용하는 것보다 효율적입니다. ST_DWithin은 색인을 활용하며 조건을 충족하면 즉시 검색을 중단하기 때문입니다.
SELECT
name,
ROUND(
ST_Distance(
location,
ST_MakePoint(28.9800, 41.0100)::geography
)::NUMERIC
) AS distance_m
FROM cafes
WHERE ST_DWithin(
location,
ST_MakePoint(28.9800, 41.0100)::geography,
2000
)
ORDER BY distance_m;반경 제한이 있는 최근접 상위 N개
실무에서 흔히 사용하는 패턴은 ST_DWithin을 사전 필터로 사용하고 <->로 정렬하는 것입니다. ST_DWithin 검사는 공간 색인을 사용해 멀리 떨어진 행을 빠르게 제거한 다음, 남은 후보를 정확한 거리순으로 정렬합니다.
이렇게 하면 최대 반경 내의 최근접 위치 N개를 매우 효율적으로 가져올 수 있습니다.
SELECT
name,
ROUND(
ST_Distance(
location,
ST_MakePoint(28.9800, 41.0100)::geography
)::NUMERIC
) AS distance_m
FROM cafes
WHERE ST_DWithin(
location,
ST_MakePoint(28.9800, 41.0100)::geography,
5000
)
ORDER BY location <-> ST_MakePoint(28.9800, 41.0100)::geography
LIMIT 3;두 테이블 사이의 거리(교차 거리)
JOIN과 ST_Distance를 함께 사용하면 서로 다른 두 테이블의 행 사이 거리를 계산할 수 있습니다. 예를 들어 각 고객을 가장 가까운 창고에 연결하거나 각 사건을 가장 가까운 병원에 연결할 때 유용합니다.
아래에서는 측면 조인을 사용해 users 테이블의 각 사용자에게 가장 가까운 카페를 찾습니다. 측면 조인은 행별 하위 쿼리에 사용할 수 있는 강력한 PostgreSQL 패턴입니다.
SELECT
u.username,
c.name AS nearest_cafe,
ROUND(ST_Distance(u.location, c.location)::NUMERIC) AS distance_m
FROM (
VALUES
('alice', ST_MakePoint(28.9810, 41.0095)::geography),
('bob', ST_MakePoint(29.0200, 41.0300)::geography)
) AS u(username, location)
CROSS JOIN LATERAL (
SELECT name, location
FROM cafes
ORDER BY location <-> u.location
LIMIT 1
) c;거리 출력 형식 지정
미터 단위의 원시 거리는 읽기 어려울 수 있습니다. CASE 표현식과 문자열 형식 지정을 사용해 거리를 킬로미터로 표시하거나 사람이 이해하기 쉬운 레이블을 추가할 수 있습니다. 다음 쿼리는 짧은 거리는 미터 단위로, 긴 거리는 킬로미터 단위로 표시합니다.
SELECT
name,
CASE
WHEN ST_Distance(location, ST_MakePoint(28.9800, 41.0100)::geography) < 1000
THEN ROUND(ST_Distance(location, ST_MakePoint(28.9800, 41.0100)::geography)::NUMERIC)
|| ' m'
ELSE ROUND((ST_Distance(location, ST_MakePoint(28.9800, 41.0100)::geography) / 1000.0)::NUMERIC, 2)
|| ' km'
END AS formatted_distance
FROM cafes
ORDER BY location <-> ST_MakePoint(28.9800, 41.0100)::geography;거리순 순위 지정
RANK()와 ROW_NUMBER() 같은 윈도 함수는 거리 쿼리와 완벽하게 결합됩니다. 사용자와의 거리를 기준으로 각 위치에 근접 순위를 지정할 수 있으므로, 순위가 매겨진 추천 목록이나 가까운 순서로 정렬된 검색 결과를 만들 때 유용합니다.
SELECT
name,
ROUND(
ST_Distance(
location,
ST_MakePoint(28.9800, 41.0100)::geography
)::NUMERIC
) AS distance_m,
ROW_NUMBER() OVER (
ORDER BY location <-> ST_MakePoint(28.9800, 41.0100)::geography
) AS proximity_rank
FROM cafes;지식 확인
PostGIS의 거리 쿼리와 최근접 이웃 조회를 얼마나 이해했는지 확인해 보세요.
레슨 요약
이 레슨에서는 PostGIS에서 공간 거리와 최근접 이웃 쿼리를 다루는 방법을 배웠습니다.
- ST_Distance는 두 기하 도형 사이의 정확한 거리를 계산합니다. 미터 단위를 자동으로 사용하려면 geography 유형을 사용하세요.
- ST_DWithin은 공간 색인을 사용해 반경 내의 행을 효율적으로 필터링합니다. WHERE 절에서는
ST_Distance < radius보다 이 함수를 우선 사용하세요. - ORDER BY의 <-> 연산자(KNN)는 색인을 활용할 수 있으며 최근접 이웃 N개를 가져오는 가장 빠른 방법입니다.
ST_DWithin을 사전 필터로 사용하고<->로 정렬하면 반경 내 상위 N개 쿼리를 가장 효율적으로 실행할 수 있습니다.- CROSS JOIN LATERAL을 사용하면 행마다 다른 테이블에서 가장 가까운 일치 항목을 찾을 수 있습니다.
ROW_NUMBER()와 같은 윈도 함수로 거리순 결과에 근접 순위를 지정할 수 있습니다.
이러한 패턴은 실제 애플리케이션에서 위치 인식 기능을 구현하는 기반이 됩니다.
자주 묻는 질문
“거리와 최근접 이웃” 강의는 무료인가요?
네 — “거리와 최근접 이웃” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 SQL Academy 강의 전체를 잠금 해제할 수 있습니다. SQL Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“거리와 최근접 이웃”에서 뭘 배우나요?
주변에 무엇이 있는지 찾아봅니다 브라우저에서 직접 실행하는 실습 코드로 SQL Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
SQL Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 SQL Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“거리와 최근접 이웃” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 SQL Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 SQL Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 공간 데이터 유형
- 거리와 최근접 이웃
- 공간 조인과 포함 관계
- 공간 인덱스(GiST)