Hiệu suất kém khi sử dụng Chỉ mục không gian trong MySQL


13

Đăng lại câu hỏi được hỏi trên Stack Overflow khi được đề xuất đây sẽ là một diễn đàn tốt hơn.

Tôi đang thử một thử nghiệm nhỏ trong việc đẩy một tập dữ liệu không phải là không gian địa lý nhưng phù hợp với nó khá tốt và đang tìm thấy kết quả hơi đáng lo ngại. Tập dữ liệu là dữ liệu gen, ví dụ Bộ gen người nơi chúng ta có một vùng DNA nơi các yếu tố như gen chiếm tọa độ bắt đầu và dừng cụ thể (trục X của chúng ta). Chúng ta có nhiều vùng DNA (nhiễm sắc thể) chiếm trục Y. Mục tiêu là mang lại tất cả các mục giao nhau với hai tọa độ X dọc theo tọa độ Y duy nhất, ví dụ LineString (START 1, END 2).

Lý thuyết có vẻ hợp lý nên tôi đã đẩy nó vào một dự án genome dựa trên MySQL hiện có và đưa ra một cấu trúc bảng như:

CREATE TABLE `spatial_feature` (
  `spatial_feature_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `external_id` int(10) unsigned NOT NULL,
  `external_type` int(3) unsigned NOT NULL,
  `location` geometry NOT NULL,
  PRIMARY KEY (`spatial_feature_id`),
  SPATIAL KEY `sf_location_idx` (`location`)
) ENGINE=MyISAM;

external_idđại diện cho định danh của thực thể mà chúng ta đã mã hóa vào bảng này và external_typemã hóa nguồn của thực thể này. Mọi thứ đều ổn và tôi đã đẩy một số dữ liệu sơ bộ (30.000 hàng) có vẻ hoạt động tốt. Khi điều này tăng vượt qua mốc 3 triệu hàng, MySQL đã từ chối sử dụng chỉ số không gian và chậm hơn khi buộc phải sử dụng nó (40 giây so với 5 giây khi quét toàn bộ bảng). Khi thêm dữ liệu, chỉ mục bắt đầu được sử dụng nhưng hình phạt hiệu suất vẫn tồn tại. Buộc chỉ mục tắt đưa truy vấn xuống còn 8 giây. Truy vấn tôi đang sử dụng trông giống như:

select count(*)
from spatial_feature
where MBRIntersects(GeomFromText('LineString(7420023 1, 7420023 1)'), location);

Dữ liệu đi vào đây rất dày đặc dọc theo kích thước Y (hãy nghĩ rằng nó giống như bạn đã ghi lại vị trí của mọi tòa nhà, hộp điện thoại, hộp thư và chim bồ câu trên một con đường rất dài). Tôi đã thực hiện các thử nghiệm về cách R-Index hoạt động với dữ liệu này trong Java cũng như các mục khác trong trường đã áp dụng chúng cho các định dạng tệp phẳng thành công. Tuy nhiên, không ai đã áp dụng chúng cho cơ sở dữ liệu AFAIK, mục tiêu của thử nghiệm này.

Có ai ở ngoài đó đã thấy một hành vi tương tự khi thêm một lượng lớn dữ liệu vào một mô hình không gian không khác biệt lắm dọc theo một trục cụ thể không? Vấn đề vẫn còn nếu tôi đảo ngược việc sử dụng tọa độ. Tôi đang chạy thiết lập sau nếu đó là một nguyên nhân

  • MacOS 10.6.6
  • MySQL 5.1.46

Câu trả lời:


5

MySQL, giống như PostGIS, lưu trữ dữ liệu chỉ mục không gian của nó trong cấu trúc cây R để nó có thể tìm thấy công cụ nhanh chóng. Cây R, giống như cây B, được tổ chức theo cách nó được tối ưu hóa để chỉ lấy một phần nhỏ của tổng dữ liệu trong bảng. Thực sự nhanh hơn khi bỏ qua chỉ mục cho các truy vấn cần đọc một phần lớn của bảng để trả về dữ liệu hoặc thực hiện một phép nối lớn, một trường hợp cổ điển làm phát sinh nhiều diễn đàn cơ sở dữ liệu [áp phích] phàn nàn về một truy vấn trả về một nửa bảng "không sử dụng chỉ mục mới mà họ vừa tạo."

Từ http://rickonrails.wordpress.com/2009/03/30/big-ole-mysql-spatial-table-optimization-tricks/

Nếu bạn có thể phù hợp với tất cả dữ liệu bảng của bạn vào bộ nhớ, hiệu suất của bạn là tốt. Nếu / khi bạn cần bắt đầu thực hiện đọc đĩa, hiệu suất nhanh chóng bị hỏng. Bạn đã thực hiện các mô hình sử dụng bộ nhớ của phiên bản mysql của mình cho hai trường hợp: 30k hàng so với 3000k hàng?


Tôi nghĩ rằng điều này có thể gần hơn với vấn đề. TBH là chỉ số R tôi muốn; các phép toán không gian khác là một phần thưởng tuyệt vời vì điều đó sẽ phải được thực hiện trong lớp API theo hệ thống cũ. Tôi đã thử điều chỉnh một chút nhưng việc tăng bộ đệm chính không giúp được gì (các bộ đệm khác sẽ không giúp ích gì ở đây như bộ đệm bảng vì đó là truy vấn 1 bảng trên máy chủ cá nhân của tôi). Điều kỳ lạ là MySQL đập máy của tôi xuống đất khi các truy vấn được chạy (100% trong khi chạy truy vấn). Điều đó nói rằng nó thực hiện quét toàn bộ bảng để có thể không có gì lạ
andeyatz

5

Một cái gì đó phải sai với cài đặt mysql của bạn hoặc cài đặt .ini. Chỉ cần thử nghiệm một chỉ số không gian địa lý trên máy mac cũ của tôi (10.6.8 / MySQL 5.2). Cấu hình đó tương tự như của bạn và tôi đã thử nghiệm bãi chứa geodata lớn ( 9 triệu bản ghi ). Tôi đã làm truy vấn này:

SET @radius = 30;
SET @center = GeomFromText('POINT(51.51359 7.465425)');
SET @r = @radius/69.1;
SET @bbox = CONCAT('POLYGON((', 
  X(@center) - @r, ' ', Y(@center) - @r, ',', 
  X(@center) + @r, ' ', Y(@center) - @r, ',', 
  X(@center) + @r, ' ', Y(@center) + @r, ',', 
  X(@center) - @r, ' ', Y(@center) + @r, ',', 
  X(@center) - @r, ' ', Y(@center) - @r, '))' 
);

SELECT geonameid, SQRT(POW( ABS( X(point) - X(@center)), 2) + POW( ABS(Y(point) - Y(@center)), 2 ))*69.1 
AS distance
FROM TABLENAME AS root
WHERE Intersects( point, GeomFromText(@bbox) ) 
AND SQRT(POW( ABS( X(point) - X(@center)), 2) + POW( ABS(Y(point) - Y(@center)), 2 )) < @r 
ORDER BY distance; 

Chỉ mất 0,0336 giây.

Tôi sử dụng truy vấn trên, ví dụ như để so sánh giữa các bảng trong đó bảng có giá trị lat / lng cho @center đến từ INDEX đơn giản từ city_latitude / city_longitude và 9-12 Mio. bảng từ geonames.org có một chỉ số không gian địa lý.

Và tôi chỉ muốn thêm rằng khi bất kỳ ai chèn dữ liệu lớn vào bảng thì có thể sẽ hiệu quả hơn để thêm chỉ mục sau INSERT. Nếu không, sẽ mất nhiều thời gian hơn cho mỗi hàng bạn thêm ... [nhưng điều đó không quan trọng]


Wow điều đó thực sự tốt. Bây giờ tôi không chắc chắn những gì tôi đã làm sai trong các bài kiểm tra của riêng tôi. Một điều có thể gây ra vấn đề là bản chất của các bộ dữ liệu của tôi so với các bộ dữ liệu không gian địa lý truyền thống hơn. Điều đó nói rằng tôi chỉ đoán và không có cơ sở cho việc này. Thật tuyệt vời khi thấy rằng bạn không cần phải buộc chỉ mục vào bộ nhớ để có được tốc độ.
andeyatz

Mệnh đề WHERE với bán kính có thể lọc ra một phần tốt của bảng từ việc sử dụng một chỉ mục.
tmarthal

2

Bạn đã nghĩ đến việc chia nó thành hai cột 1D thay vì một cột 2D chưa?

Trình tối ưu hóa có thể gây nghẹt thở trên tất cả các dữ liệu tương tự và có hai cột với sự đa dạng hơn có thể giúp ích.

Những gì bạn cũng có thể kiểm tra là thứ tự các mục được kiểm tra. Tôi gặp vấn đề trong Oracle Spatial khi tôi tìm kiếm trên Last Name và bộ lọc IN_REGION. Oracle quyết định cách nhanh nhất là sử dụng tên cuối cùng và sau đó thực hiện kiểm tra khu vực. Hãy để tôi nói với bạn, thực hiện kiểm tra trong khu vực đối với tất cả các Robinson ở Cleveland là chậm . Tôi nhớ rằng tôi đã phải vượt qua một đối số cụ thể của Oracle để buộc nó sử dụng chỉ mục không gian trước tiên.


Thật không may, 1 chiều ít dân cư hơn so với các chiều khác. Để đưa điều này vào bối cảnh, bộ gen của con người có 24 nhiễm sắc thể độc nhất (22 cặp và hai nhiễm sắc thể giới tính) cùng với một túi dữ liệu đã được lắp ráp ở các cấp độ khác nhau. Điều đó có nghĩa là nếu bạn ánh xạ các phần tử vào trường hợp sử dụng cơ bản chỉ có 24 định danh duy nhất trong một chiều. Hy vọng ban đầu là chỉ số cây R sẽ có thể thực hiện không chỉ kiểm tra phạm vi chồng chéo hiệu quả hơn mà còn phân biệt giữa các khu vực này trong một truy vấn duy nhất.
andeyatz
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.