Cách nhanh nhất để làm điều này là sử dụng các phần mở rộng không gian địa lý cho MySQL, điều này sẽ đủ dễ dàng vì bạn đang sử dụng bảng MyISAM. Bạn có thể tìm thấy tài liệu cho các tiện ích mở rộng này tại đây: http:/ /dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html
Thêm cột mới với kiểu dữ liệu POINT:
ALTER TABLE `adverts`
ADD COLUMN `geopoint` POINT NOT NULL AFTER `longitude`
ADD SPATIAL KEY `geopoint` (`geopoint`)
Sau đó, bạn có thể điền cột này từ các trường kinh độ và vĩ độ hiện có của mình:
UPDATE `adverts`
SET `geopoint` = GeomFromText(CONCAT('POINT(',`latitude`,' ',`longitude`,')'));
Bước tiếp theo là tạo một hộp giới hạn dựa trên vĩ độ và kinh độ đầu vào sẽ được sử dụng trong WHERE
của bạn mệnh đề dưới dạng CONTAINS
hạn chế. Bạn sẽ cần xác định một tập hợp X, Y POINT
tọa độ phù hợp với yêu cầu của bạn dựa trên khu vực tìm kiếm mong muốn và điểm xuất phát đã cho.
Truy vấn cuối cùng của bạn sẽ tìm kiếm tất cả POINT
dữ liệu trong tìm kiếm của bạn POLYGON
và sau đó, bạn có thể sử dụng tính toán khoảng cách để tinh chỉnh và sắp xếp thêm dữ liệu của mình:
SELECT a.*,
ROUND( SQRT( ( ( (adverts.latitude - '53.410778') * (adverts.latitude - '53.410778') ) * 69.1 * 69.1 ) + ( (adverts.longitude - '-2.97784') * (adverts.longitude - '-2.97784') * 53 * 53 ) ), 1 ) AS distance
FROM adverts a
WHERE a.type_id = 3
AND CONTAINS(a.geopoint, GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'))
HAVING distance < 25
ORDER BY distance DESC
LIMIT 0, 30
Lưu ý rằng GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))')
ở trên sẽ không hoạt động , bạn sẽ cần thay thế các tọa độ bằng các điểm hợp lệ xung quanh điểm bắt đầu tìm kiếm của mình. Nếu bạn mong đợi vĩ độ / thời gian thay đổi, bạn nên cân nhắc sử dụng trình kích hoạt để giữ POINT
dữ liệu và SPATIAL KEY
được liên kết cập nhật. Với tập dữ liệu lớn, bạn sẽ thấy hiệu suất được cải thiện đáng kể khi tính toán khoảng cách cho mọi bản ghi và lọc bằng cách sử dụng HAVING
mệnh đề. Cá nhân tôi đã xác định các hàm để sử dụng trong việc xác định khoảng cách và tạo POLYGON
giới hạn .