Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Chỉ mục không gian không được sử dụng

Rất tiếc, ST_Distance() < threshold không phải là sargable tiêu chí tìm kiếm. Để đáp ứng truy vấn này, MySQL phải tính toán giá trị của hàm cho mọi hàng trong bảng, sau đó so sánh nó với ngưỡng. Vì vậy, nó phải thực hiện quét toàn bộ bảng (hoặc có thể quét toàn bộ chỉ mục).

Để khai thác một chỉ mục để tăng tốc truy vấn này, bạn sẽ cần một tiêu chí hộp giới hạn. Truy vấn phức tạp hơn rất nhiều nhưng cũng nhanh hơn rất nhiều. Giả sử các điểm x / y trong hình học của bạn đại diện cho vĩ độ / kinh độ theo độ, truy vấn đó có thể trông giống như sau:

   set @latpoint = 38.0234332;
   set @lngpoint = -94.0724223;
   set @r = 10.0;    /* ten mile radius */
   set @units=69.0;    /* 69 statute miles per degree */
   SELECT AsText(geo) 
     FROM markers
      WHERE MbrContains(GeomFromText( 
       CONCAT('LINESTRING(', @latpoint-(@r/@units),' ',
                             @lngpoint-(@r /(@units* COS(RADIANS(@latpoint)))), 
                          ',', 
                             @latpoint+(@r/@units) ,' ', 
                             @lngpoint+(@r /(@units * COS(RADIANS(@latpoint)))),
                           ')')),
                    geo) 

Cái này hoạt động ra sao? Đối với một điều, MbrContains ( ràng buộc, mục) chức năng sargable . Đối với một điều khác, mục concat xấu xí lớn tạo ra một đường chéo từ tây nam đến góc đông bắc của hình chữ nhật giới hạn. Sử dụng điểm dữ liệu của bạn và bán kính mười dặm, nó trông giống như thế này.

LINESTRING(37.8785 -94.2564,38.1684 -93.8884)

Khi bạn sử dụng GeomFromText() hiển thị đường chéo đó trong đối số đầu tiên thành MbrContains() nó phục vụ như một hình chữ nhật giới hạn. MbrContains() sau đó có thể khai thác chỉ mục hình học quadtree tiện lợi.

Thứ ba, ST_Distance() , trong MySQL, không xử lý các phép tính kinh độ và vĩ độ vòng tròn tuyệt vời. ( PostgreSQL tiện ích mở rộng GIS toàn diện hơn .) MySQL thì ngớ ngẩn như một cú lật mặt trong vùng đất phẳng. Nó giả định rằng các điểm của bạn trong các đối tượng hình học của bạn được biểu diễn dưới dạng hình học phẳng. Vì vậy, ST_Distance() < 10.0 với các điểm lng / lat thực hiện một điều gì đó kỳ lạ.

Có một lỗ hổng trong kết quả mà truy vấn này tạo ra; nó trả về tất cả các điểm trong hộp giới hạn, không chỉ trong bán kính được chỉ định. Điều đó có thể giải quyết được với một tính toán khoảng cách riêng biệt. Tôi đã viết tất cả điều này một số chi tiết ở đây .

Lưu ý :Đối với kinh độ và vĩ độ có độ phân giải GPS, FLOAT 32 bit dữ liệu có đủ độ chính xác. DOUBLE là những gì tiện ích mở rộng địa lý của MySQL sử dụng. Khi bạn làm việc theo độ, hơn năm vị trí sau dấu thập phân vượt quá độ chính xác của GPS. DECIMAL() không phải là kiểu dữ liệu lý tưởng cho tọa độ vĩ độ / lng.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để viết một (MySQL) LIMIT trong SQL Server?

  2. Cách ẩn thủ tục được lưu trữ mysql

  3. Lỗi 1064 với CodeIgniter trong bảng ci_sessions

  4. Có tương đương với SHA1 () trong MS-SQL không?

  5. xuất sử dụng bộ nhớ từ cơ sở dữ liệu sang csv trong php