ST\_Contains
ST_Contains
ST_Contains 함수는 두 번째 지오메트리/지리의 어떤 점도 첫 번째 지오메트리/지리의 외부에 있지 않고, 첫 번째 지오메트리의 내부 점이 적어도 하나는 두 번째 지오메트리의 내부에 있을 때만 true를 반환하는 함수예요.
출처: 문서
본문
두 번째 지오메트리/지리의 어떤 점도 첫 번째 지오메트리/지리의 외부에 있지 않고, 첫 번째 지오메트리의 내부 점이 적어도 하나는 두 번째 지오메트리의 내부에 있을 때만 true를 반환해요.
시그니처 (Signature)
ST_Contains(geometry/geography, geometry/geography)
경고 (Warning)
Geography에 대한 ST_Contains는 근사치만 제공해요: 지리 객체에 지오메트리 계산을 사용하므로, 작은 영역에서는 근사치가 잘 맞지만 180번째 경도를 가로지르는 영역에서는 잘 동작하지 않아요.
사용 예시 (Usage Examples)
다음 예시는 Streaming Quick Start를 기반으로 해요.
select group_city,
ST_AsText(location) AS locationString,
ST_Contains(
ST_GeomFromText('POLYGON ((
-74.171737 40.607377,
-74.089339 40.753180,
-73.911498 40.769303,
-74.016555 40.604249,
-74.171737 40.607377))'),
toGeometry(location)
) AS inPolygon
from meetupRsvp
order by inPolygon DESC
limit 5
| group_city | locationString | inPolygon |
|---|---|---|
| New York | POINT (-73.99 40.75) | 1 |
| New York | POINT (-73.99 40.75) | 1 |
| Staten Island | POINT (-74.15 40.61) | 1 |
| New York | POINT (-73.99 40.75) | 1 |
| New York | POINT (-73.99 40.75) | 1 |
select count(*)
from meetupRsvp
WHERE ST_Contains(
ST_GeomFromText('POLYGON ((
-74.171737 40.607377,
-74.089339 40.753180,
-73.911498 40.769303,
-74.016555 40.604249,
-74.171737 40.607377))'),
toGeometry(location)
) = 1
| count(*) |
|---|
| 8 |
쿼리는 인덱스를 사용할 수 있도록 WHERE 절에서 인덱스된 지오메트리/지리 컬럼을 변환하지 않아야 해요. 위 예시의 ST_Contains 내에서 location을 지오메트리로 변환하면 인덱스가 비활성화돼요. 대신 컬럼 타입에 맞게 리터럴을 변환하는 것이 좋아요:
select count(*)
from meetupRsvp
WHERE ST_Contains(
ST_GeogFromText('POLYGON ((
-74.171737 40.607377,
-74.089339 40.753180,
-73.911498 40.769303,
-74.016555 40.604249,
-74.171737 40.607377))'),
location ) = 1
인덱스 사용은 EXPLAIN 명령으로 확인할 수 있어요:
SET explainAskingServers=true;
explain plan for
SELECT event_id
FROM meetupRsvp
WHERE ST_Contains(
ST_GeogFromText('POLYGON ((
-74.171737 40.607377,
-74.089339 40.753180,
-73.911498 40.769303,
-74.016555 40.604249,
-74.171737 40.607377))'), location) = 1
limit 1000
이 쿼리는 다음과 같이 끝나는 계획을 반환해야 해요:
Project(columns=[[event_id]])
DocIdSet(maxDocs=[10000])
InclusionFilterH3Index(predicate=[stcontains('84000000010000000500000000c0528afdbd2fa0d740444dbe878fabdac05285b7baecd0784044606833c6002ac0527a55fbb517a440446278854cdb7bc052810f3cb3e57540444d5807fed203c0528afdbd2fa0d740444dbe878fabda',location) = '1'], operator=[EQ])
여기서 InclusionFilterH3Index는 쿼리가 H3 인덱스 조회를 사용한다는 뜻이에요.