Làm cách nào để tìm kiếm hiệu quả tất cả các mốc trong phạm vi của một mốc nhất định?


14

Tôi cố gắng để bắt đầu với một dự án tìm kiếm geo rằng sẽ tìm thấy tất cả các địa danh tại 10 km / dặm (không quan trọng cho câu chuyện này) của một cột mốc cụ thể.

Vì vậy, ví dụ, giả sử tôi có cơ sở dữ liệu gồm 1.000.000 mốc. Để tìm tất cả các địa danh tại 10 dặm dao động của một bước ngoặt với tọa độ nào đó, tôi sẽ phải tính toán khoảng cách giữa một mốc từ tìm kiếm của tôi và 1.000.000 mốc.

Có cách nào tốt hơn để làm điều đó?

Thay thế tôi đã nghĩ là phân loại các địa danh như quốc gia, khu vực, thành phố, khu phố, kinh doanh, lịch sử, vv theo cách mà doanh nghiệp có thể là một phần của một khu phố hoặc thành phố. Thành phố là một phần của một khu vực, một quốc gia, v.v ... Điều này có thể thu hẹp danh sách các tính toán, nhưng có vẻ như vẫn còn rất nhiều việc phải làm để tìm kiếm nhanh và chính xác.

API Google Maps có thể giúp được không?


5
Bạn có thể có thể loại bỏ rất nhiều thứ đơn giản bằng cách thực hiện phép tính khoảng cách Manhattan nhanh chóng và sau đó thực hiện bộ lọc thứ hai sau đó để loại trừ các mốc nằm trong phạm vi 10km vuông nhưng nằm ngoài bán kính 10km.
Neil

3
Bạn đang sử dụng công nghệ cơ sở dữ liệu nào? Câu trả lời không phải là cơ sở dữ liệu bất khả tri.
jpmc26

1
@Neil Khi vượt qua lần thứ hai, bạn có thể bao gồm bất kỳ mốc nào mà cả x và y đều rơi trong 7km gốc mà không tính khoảng cách thực tế.
JimmyJames

Câu trả lời:


10

Kể từ SQL Server 2008, có một địa lý kiểu dữ liệu lưu trữ các vị trí (cặp lat / lon) và giúp bạn dễ dàng viết các truy vấn liên quan đến vị trí.

Có một câu trả lời StackOverflow hiện có thảo luận sâu về vấn đề này.

Một truy vấn cơ bản để tìm 7 mục gần nhất :

USE AdventureWorks2012  
GO  
DECLARE @g geography = 'POINT(-121.626 47.8315)';  
SELECT TOP(7) SpatialLocation.ToString(), City FROM Person.Address  
WHERE SpatialLocation.STDistance(@g) IS NOT NULL  
ORDER BY SpatialLocation.STDistance(@g);  

Một truy vấn cơ bản để tìm mọi thứ trong vòng 100m (câu trả lời thứ hai cho câu hỏi)

-- Get the center point
DECLARE @g geography
SELECT @g = geo FROM yourTable WHERE PointId = something

-- Get the results, radius 100m
SELECT * FROM yourTable WHERE @g.STDistance(geo) <= 100

11
@KonradRudolph: Như trường hợp của bất kỳ cột SQL nào được sử dụng để truy vấn trên một bảng có số lượng hàng lớn. Bạn đã đúng, nhưng nhận xét đó sẽ áp dụng cho hầu như mọi truy vấn SQL được đăng dưới dạng câu trả lời.
Flater

2
Bạn đã đọc "MS SQL Server" ở đâu trong câu hỏi?
Doc Brown

3
@Flater Tôi đồng ý rằng nó thường sẽ rõ ràng và dư thừa nhưng từ ngữ của OP dường như cho thấy rằng họ không biết về các cơ chế như vậy.
Konrad Rudolph

2
@ jpmc26: Bạn đang kinh hoàng rằng tôi đã liệt kê một tùy chọn hợp lệ và không bao gồm một số tùy chọn khác? Gì? Nếu bạn cảm thấy có liên quan để thêm PostGIS, hãy tự thêm câu trả lời (mà bạn đã làm) và không dùng đến việc chỉ trích người khác vì không có cùng ý tưởng với bạn.
Flater

3
Câu trả lời của bạn xuất hiện với tôi về cơ bản chỉ là một quảng cáo bán hàng MS SQL. Nhận xét của bạn cho thấy họ chuyển cơ sở dữ liệu sang thứ gì đó có giá 10 nghìn đô la mà không thực sự tìm hiểu về tình huống của họ chỉ khiến nó xuất hiện ngay từ đầu. Nó thậm chí không mô tả làm thế nào OP thực sự có thể thực hiện truy vấn của họ hoặc thảo luận về thực tế là làm như vậy và bảo vệ chỉ số không gian được sử dụng không đơn giản như trong MS SQL như trong các DB khác. Nó cũng không thảo luận về bất kỳ khái niệm cơ bản. Đó là một câu trả lời tồi, bất kể nó "hợp lệ". Đó là lý do tại sao nó làm phiền tôi.
jpmc26

29

Sử dụng cơ sở dữ liệu với sự hỗ trợ cho các truy vấn GIS (hệ thống thông tin địa lý) . Hầu hết các cơ sở dữ liệu đều hỗ trợ hoàn toàn hoặc có phần mở rộng, nhưng các chi tiết sẽ dành riêng cho cơ sở dữ liệu (trong câu trả lời của họ , Flater hiển thị cú pháp cho máy chủ SQL).

Nếu bạn cần triển khai các truy vấn như vậy trong ứng dụng của mình, bạn có thể triển khai cấu trúc dữ liệu cho phép truy vấn không gian, ví dụ: Cây kd . Đây giống như một cây tìm kiếm nhị phân, ngoại trừ mỗi cấp của các phân vùng cây trên một thứ nguyên tọa độ khác nhau. Điều này cho phép bạn giới hạn tìm kiếm trong một nhóm nhỏ hơn các ứng cử viên khả thi. Thực tế, bạn dịch tìm kiếm của bạn Bán kính 10km bán kính của bạn thành các giới hạn cho mỗi kích thước tọa độ và thắt chặt các giới hạn khi bạn lặp lại vào cây.



8
PostGIS là tùy chọn miễn phí hàng đầu. Nó hỗ trợ nhiều, nhiều hơn các loại và chức năng GIS rất cơ bản của SQL Server. Nhưng đây là chức năng cơ bản.
jpmc26

@amon Tôi thấy nhận xét của jpmc26 là một bổ sung tốt, và không nhiều như chỉ trích ví dụ của bạn. "Nếu bạn muốn bắt đầu lại từ đầu, bạn không cần phải trả tiền cho một DB được cấp phép - mã nguồn mở, miễn phí này cũng sẽ thực hiện thủ thuật rất tốt".
mgarciaisaia

11

Vâng, có một cách tốt hơn. Bạn cần sử dụng một chỉ số không gian . Các chỉ mục này tổ chức siêu dữ liệu về hình học để lọc ra hình học ở rất xa, tiết kiệm rất nhiều chu kỳ CPU bằng cách tránh các tính toán mà bạn mô tả. Bạn không nên tự mình thực hiện vì tất cả các cơ sở dữ liệu quan hệ chính đều cung cấp loại hình và chỉ mục hình học không gian đi kèm với chúng.

Những gì bạn muốn xem xét là các truy vấn "trong khoảng cách" (truy vấn cho hình học trong một khoảng cách nhất định của một số hình học khác). Đây là những vấn đề rất chuẩn và rất nhiều đã được giải quyết và có thể có trong tất cả các cơ sở dữ liệu trên (và được tích hợp vào một số):

  • PostGIS: ST_DWithin
  • Máy chủ SQL: STDistance (Không rõ rằng chỉ mục sử dụng trên phiên bản địa lý 3D của chức năng này được hỗ trợ)
  • Oracle: SDO_WITHIN_DISTANCE(Điều này không nói rõ ràng rằng nó sẽ kích hoạt việc sử dụng chỉ mục. Tôi sẽ kiểm tra lại kế hoạch truy vấn. Bạn có thể cần phải áp dụng mộtSDO_FILTER để có được nó để sử dụng chỉ mục.)
  • MySQL: Vẫn đang tìm ra điều này.

Giải pháp cho việc kích hoạt sử dụng chỉ mục

Trong trường hợp xấu nhất khi bạn gặp sự cố khiến hệ thống sử dụng chỉ mục không gian với các truy vấn này, bạn có thể thêm bộ lọc bổ sung. Bạn sẽ tạo một hộp giới hạn hình vuông có cạnh dài 2 * (khoảng cách tìm kiếm) tập trung tại điểm tìm kiếm của bạn và so sánh các hộp giới hạn của hình học bảng với điều đó trước khi kiểm tra khoảng cách thực tế. Đó là những gì PostGIS ' ST_DWithinở trên thực hiện trong nội bộ.


Khoảng cách trong GIS

Trong khi các chỉ số không gian là tuyệt vời và hoàn toàn là giải pháp phù hợp cho vấn đề của bạn, việc tính toán khoảng cách có thể trở nên phức tạp về mặt logic. Cụ thể, bạn cần lo lắng về phép chiếu nào (về cơ bản là tất cả các tham số cho hệ tọa độ), dữ liệu của bạn được lưu trữ. Hầu hết các phép chiếu 2D (những thứ khác ngoài hệ tọa độ góc như các phép chiếu lat / long khác nhau) làm biến dạng đáng kể độ dài. Ví dụ: phép chiếu Web Mercator (được sử dụng bởi Google, Bing và mọi nhà cung cấp bản đồ cơ sở chính khác) mở rộng các khu vực và khoảng cách ngày càng tăng khi vị trí nằm xa xích đạo hơn . Tôi có thể sai vì tôi không được giáo dục chính thức về GIS, nhưng điều tốt nhất tôi từng thấy cho các phép chiếu 2D là một số cách cụ thể hứa hẹn khoảng cách chính xác từ mộtđiểm duy nhất, không đổi trên toàn thế giới. (Không, việc sử dụng một phép chiếu khác nhau cho mỗi truy vấn là không thực tế; điều đó sẽ khiến các chỉ mục của bạn trở nên vô dụng.)

Điểm mấu chốt là bạn cần đảm bảo rằng toán học của bạn là chính xác. Cách đơn giản nhất để làm như vậy từ góc độ phát triển là sử dụng các phép chiếu góc (Chúng thường được gọi là "địa lý") và các hàm hỗ trợ làm toán bằng mô hình hình cầu, nhưng các tính toán này đắt hơn một chút so với các đối tác 2D và một số DB có thể không hỗ trợ lập chỉ mục chúng. Tuy nhiên, nếu bạn có thể có được hiệu suất chấp nhận được bằng cách sử dụng chúng, thì đó có lẽ là cách tốt nhất. Một tùy chọn phổ biến khác là các phép chiếu khu vực (như các vùng UTM) có cả khoảng cách và các khu vực khá gần để sửa nếu dữ liệu của bạn bị giới hạn ở một phần cụ thể của thế giới. Những gì tốt nhất cho ứng dụng của bạn sẽ phụ thuộc vào yêu cầu cụ thể của bạn,

Điều này áp dụng ngay cả khi bạn không sử dụng các chỉ mục không gian tích hợp. Dữ liệu của bạn có một số phép chiếu bất kể bạn đang sử dụng hoặc sử dụng công nghệ hoặc kỹ thuật nào trong tương lai và hiện tại nó đã ảnh hưởng đến bất kỳ truy vấn và tính toán nào bạn đang thực hiện.


3

Tôi đồng ý rằng nếu có thể sử dụng hỗ trợ cụ thể trong cơ sở dữ liệu sẽ là cách hợp lý nhất để làm điều này.

Tuy nhiên, nếu tôi phải làm điều này trên cơ sở dữ liệu mà không có sự hỗ trợ cụ thể, tôi sẽ bắt đầu bằng cách truy vấn một hình vuông có chứa hình tròn, ví dụ (y> (y1 - rad)) AND (y <(y1 + rad)) AND (x> ( x1 - rad)) VÀ (x <(x1 + rad)). Giả sử các điểm của bạn có truy vấn phân phối gần như bằng nhau cho một hình vuông sẽ giúp bạn có được các trận đấu thực sự của bạn cộng thêm khoảng 30% kết quả khớp sai. Sau đó, bạn có thể loại bỏ các trận đấu sai.


Nhưng không có chỉ số không gian phù hợp, truy vấn như vậy sẽ quét toàn bộ cơ sở dữ liệu, tốt nhất là tất cả các mục trong phạm vi kinh độ HOẶC vĩ độ đã cho tùy thuộc vào chỉ mục của bạn, tức là "dải" thay vì hình vuông. Nếu bạn không muốn giết hiệu suất, hãy sử dụng cơ sở dữ liệu hỗ trợ các chỉ mục không gian!
jcaron

@jcaron Tôi tin rằng truy vấn này có thể được tối ưu hóa với chỉ mục cây B thông thường trên xy. (Có lẽ kết hợp, có lẽ tách biệt. Tôi sẽ mô tả một chút để tìm ra cách nào hiệu quả hơn trong thực tế.)
jpmc26

@ jpmc26 Không, không thể. Hãy suy nghĩ kỹ, bạn sẽ thấy.
jcaron

@jcaron Có lẽ sẽ tốt hơn nếu bạn không khó hiểu về điều gì đó rõ ràng không đơn giản. Cây B có thể được sử dụng cho BETWEENcác truy vấn. Tôi không hiểu tại sao trường hợp xấu nhất bạn không thể có 2 chỉ mục và sau đó các kết quả được lọc từ mỗi chỉ mục được nối với nhau. (Đó là điều mà RDBMS thực hiện trong nội bộ khi họ cho rằng nó đáng để sử dụng nhiều chỉ mục.) Nếu một chỉ mục kết hợp hoạt động, nó sẽ lọc ra một chiều hoàn toàn ở cấp độ đầu tiên và sau đó thu hẹp tương đối nhanh chóng ở cấp độ thứ hai.
jpmc26

2
@jcaron thực sự bạn có thể sử dụng chỉ mục cho một cái gì đó giống như y between -68 and -69 and x between 10 and 11nhưng tất nhiên chỉ số không gian thực hiện công việc tốt hơn cho nhiệm vụ đó
Juan Carlos Oropeza
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.