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.