MySQL에서 공간 인덱스를 사용할 때 성능 저하


13

스택 오버플로에 대한 질문을 다시 게시하면 더 나은 포럼이 될 것이라고 제안되었습니다.

지리 공간이 아니지만 데이터에 잘 맞는 데이터 세트를 푸시하는 데 약간의 실험을 시도하고 있으며 결과가 다소 불안정합니다. 데이터 세트는 게놈 데이터입니다. 예를 들어 유전자와 같은 요소가 특정 시작 및 정지 좌표 (우리의 X 축)를 차지하는 DNA 영역이있는 인간 게놈입니다. Y 축을 차지하는 DNA의 여러 영역 (염색체)이 있습니다. 목표는 단일 Y 좌표를 따라 두 개의 X 좌표와 교차하는 모든 항목을 다시 가져 오는 것입니다 (예 : LineString (START 1, END 2)).

이론은 소리처럼 보였으므로 기존 MySQL 기반 게놈 프로젝트에 적용하고 다음과 같은 테이블 구조를 생각해 냈습니다.

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이 테이블에 인코딩 한 엔터티의 식별자를 나타내며 external_type소스를 인코딩합니다. 모든 것이 좋아 보였고 잘 작동하는 것처럼 보이는 예비 데이터 (30,000 행)를 밀어 넣었습니다. 이 수가 3 백만 행을 넘어서 증가했을 때 MySQL은 공간 인덱스 사용을 거부했으며 강제로 사용할 때 속도가 느려졌습니다 (전체 테이블 스캔을 사용하여 40 초 대 5 초). 더 많은 데이터가 추가되면 인덱스가 사용되기 시작했지만 성능 저하가 지속되었습니다. 인덱스를 강제로 끄면 쿼리가 8 초로 줄었습니다. 내가 사용하는 쿼리는 다음과 같습니다.

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

여기에 들어가는 데이터는 Y 차원을 따라 매우 밀도가 높습니다 (매우 긴 도로에서 모든 건물, 전화 함, 우편함 및 비둘기의 위치를 ​​기록한 것처럼 생각하십시오). R-Index가 Java 에서이 데이터와 어떻게 작동하는지 테스트하고 현장의 다른 사람들이이를 플랫 파일 형식으로 성공적으로 적용했습니다. 그러나 아무도이 테스트의 목표 인 데이터베이스 AFAIK에 적용하지 않았습니다.

특정 축을 따라 별다른 차이가없는 공간 모델에 대량의 데이터를 추가 할 때 비슷한 동작을 본 사람이 있습니까? 좌표 사용을 반대로해도 문제가 지속됩니다. 그 원인이라면 다음 설정을 실행 중입니다.

  • 맥 OS 10.6.6
  • MySQL 5.1.46

답변:


5

PostGIS와 마찬가지로 MySQL은 공간 인덱스 데이터를 R- 트리 구조로 저장하므로 빠르게 찾을 수 있습니다. B- 트리와 같은 R- 트리는 테이블의 전체 데이터 중 일부만 검색하도록 최적화 된 방식으로 구성됩니다. 실제로 데이터를 반환하거나 큰 조인을 수행하기 위해 테이블의 큰 섹션을 읽어야하는 쿼리의 인덱스를 무시하는 것이 더 빠릅니다. "방금 만든 새 색인을 사용하지 않습니다."

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

모든 테이블 데이터를 메모리에 맞추면 성능이 좋아집니다. 디스크 읽기를 시작해야하는 경우 성능이 빠르게 저하됩니다. 30k 행과 3000k 행의 두 가지 경우에 mysql 인스턴스의 메모리 사용 패턴을 수행하고 있습니까?


이것이 문제에 더 가깝다고 생각합니다. TBH 내가 원하는 R- 지수; 다른 공간 수학은 이전 시스템의 API 계층에서 수행되어야하기 때문에 좋은 보너스입니다. 약간의 조정을 시도했지만 키 버퍼를 늘리는 것이 도움이되지 않았습니다 (다른 버퍼는 개인 서버의 1 테이블 쿼리이므로 테이블 버퍼와 같이 여기에서는 도움이되지 않습니다). 이상한 점은 MySQL이 쿼리가 실행될 때 (쿼리 실행 중 100 %) 내 컴퓨터를 망치게한다는 것입니다. 그것은 전체 테이블 스캔을 수행하고 그렇게 이상하지 않을 것이라고 말했다
— andeyatz

5

mysql 설치 또는 .ini 설정에 문제가 있어야합니다. 이전 Mac (10.6.8 / MySQL 5.2)에서 지리 공간 인덱스를 테스트했습니다. 이 구성은 귀하의 구성과 유사하며 큰 지리 데이터 덤프 ( 9 백만 레코드 )를 테스트했습니다 . 나는이 쿼리를했다 :

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; 

0.0336 초 밖에 걸리지 않았습니다.

위의 쿼리를 사용합니다. 예를 들어 @center의 위도 / 경도 값이 나오는 테이블이 city_latitude / city_longitude 및 9-12 Mio의 일반 INDEX를 갖는 테이블 간의 비교에 사용합니다. geonames.org의 테이블에는 지리 공간 인덱스가 있습니다.

그리고 누군가가 큰 데이터를 테이블에 삽입 할 때 INSERT 후에 인덱스를 추가하는 것이 더 효과적 일 수 있다고 덧붙였습니다. 그렇지 않으면 각 행마다 시간이 더 오래 걸립니다 ... [하지만 중요하지 않습니다]


와우 정말 좋다. 이제 내 테스트에서 내가 뭘 잘못하고 있는지 잘 모르겠습니다. 문제를 일으킬 수있는 한 가지 방법은 기존의 지리 공간 데이터 세트와 비교하여 내 데이터 세트의 특성입니다. 그것은 내가 추측하고 있고 이것에 대한 근거가 없다고 말했다. 속도를 얻기 위해 인덱스를 메모리에 강제로 넣을 필요가 없다는 것을 알게되었습니다.
— andeyatz

반지름이있는 WHERE 절은 인덱스를 사용하여 테이블의 상당 부분을 필터링 할 수 있습니다.
— tmarthal

2

단일 2D 열 대신 두 개의 1D 열로 나누는 것에 대해 생각해 보셨습니까?

옵티마이 저는 모든 유사한 데이터를 질식시킬 수 있으며 더 많은 다양성을 가진 두 개의 열이 있으면 도움이 될 수 있습니다.

확인할 사항은 항목을 확인한 순서입니다. Oracle Spatial에서 성 및 IN_REGION 필터를 검색하는 데 문제가있었습니다. 오라클은 가장 빠른 방법은 성을 사용한 다음 지역 확인을 수행하는 것이라고 결정했습니다. 클리블랜드의 모든 로빈슨에 대해 지역 내 점검을하는 것은 느립니다 . 공간 인덱스를 먼저 사용하려면 Oracle 특정 인수를 전달해야한다는 것을 기억합니다.


불행하게도 1 차원은 다른 차원보다 훨씬 덜 채워집니다. 이러한 맥락에서 인간 게놈은 24 가지의 고유 한 염색체 (22 쌍과 두 개의 성 염색체)와 다른 수준으로 조립 된 데이터 백을 가지고 있습니다. 이는 한 차원에서 24 개의 고유 식별자 인 기본 유스 케이스에 요소를 맵핑하는 경우를 의미합니다. 원래의 희망은 R- 트리 인덱스가 더 많은 성능의 겹치는 범위 검사를 수행 할 수 있었을뿐만 아니라 단일 쿼리에서 이러한 영역을 구별 할 수 있었을 것이라는 것이 었습니다.
— andeyatz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.