Đối với MySQL 5.7+
Cho chúng ta có bảng đơn giản sau,
create table example (
id bigint not null auto_increment primary key,
lnglat point not null
);
create spatial index example_lnglat
on example (lnglat);
Với dữ liệu đơn giản sau,
insert into example (lnglat)
values
(point(-2.990435, 53.409246)),
(point(-2.990037, 53.409471)),
(point(-2.989736, 53.409676)),
(point(-2.989554, 53.409797)),
(point(-2.989350, 53.409906)),
(point(-2.989178, 53.410085)),
(point(-2.988739, 53.410309)),
(point(-2.985874, 53.412656)),
(point(-2.758019, 53.635928));
Bạn sẽ nhận được các điểm trong một phạm vi nhất định của một điểm khác (lưu ý:chúng ta phải tìm kiếm bên trong một đa giác) với sự kết hợp của các hàm st sau:
set @px = -2.990497;
set @py = 53.410943;
set @range = 150; -- meters
set @rangeKm = @range / 1000;
set @search_area = st_makeEnvelope (
point((@px + @rangeKm / 111), (@py + @rangeKm / 111)),
point((@px - @rangeKm / 111), (@py - @rangeKm / 111))
);
select id,
st_x(lnglat) lng,
st_y(lnglat) lat,
st_distance_sphere(point(@px, @py), lnglat) as distance
from example
where st_contains(@search_area, lnglat);
Kết quả là bạn sẽ thấy một cái gì đó như thế này:
3 -2.989736 53.409676 149.64084252776277
4 -2.989554 53.409797 141.93232714661812
5 -2.98935 53.409906 138.11516275402533
6 -2.989178 53.410085 129.40289289527473
Để tham khảo về khoảng cách, nếu chúng ta loại bỏ ràng buộc, kết quả cho điểm kiểm tra sẽ giống như sau:
1 -2.990435 53.409246 188.7421181457556
2 -2.990037 53.409471 166.49406509160158
3 -2.989736 53.409676 149.64084252776277
4 -2.989554 53.409797 141.93232714661812
5 -2.98935 53.409906 138.11516275402533
6 -2.989178 53.410085 129.40289289527473
7 -2.988739 53.410309 136.1875540498202
8 -2.985874 53.412656 360.78532732013963
9 -2.758019 53.635928 29360.27797292756
Lưu ý 1 :trường được gọi là lnglat vì đó là thứ tự chính xác nếu bạn coi các điểm là (x, y) và cũng là thứ tự mà hầu hết các hàm (như point) chấp nhận tham số
Lưu ý 2 :bạn thực sự không thể tận dụng chỉ mục không gian nếu bạn sử dụng các vòng kết nối; cũng lưu ý rằng trường điểm có thể được đặt để chấp nhận null nhưng các chỉ mục không gian không thể lập chỉ mục nó nếu nó có thể là null (tất cả các trường trong chỉ mục được yêu cầu không phải là null).
Lưu ý 3 :st_buffer được coi là (theo tài liệu) là không tốt cho trường hợp sử dụng này
Lưu ý 4 :các hàm trên (cụ thể là st_distance_sphere) được ghi lại là nhanh nhưng không nhất thiết phải siêu chính xác; nếu dữ liệu của bạn siêu nhạy cảm, hãy thêm một chút khoảng trống cho tìm kiếm và thực hiện một số tinh chỉnh đối với tập kết quả