2011-05-05 5 views
3

내 표는 현재이 같은 약자GEO 데이터와 함께 사용하기 위해이 MySQL 테이블을 인덱싱하는 방법은 무엇입니까?

CREATE TABLE IF NOT EXISTS `x_geodata` (
    `post_id` int(11) NOT NULL, 
    `post_type` varchar(20) NOT NULL, 
    `lat` float(10,6) NOT NULL, 
    `lng` float(10,6) NOT NULL, 
    PRIMARY KEY (`post_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

어떻게 정확하고 효율적으로 INDEX이 표는 무엇입니까?

if(!empty($_SESSION['s_property_radius'])) {$dist = $_SESSION['s_property_radius'];}else{$dist = 50;} 
$orig_lat = $_SESSION['s_property_address_lat']; 
$orig_lon = $_SESSION['s_property_address_lng']; 
$lon1 = $orig_lon - $dist/abs(cos(deg2rad($orig_lat)) * 69); 
$lon2 = $orig_lon + $dist/abs(cos(deg2rad($orig_lat)) * 69); 
$lat1 = $orig_lat - ($dist/69); 
$lat2 = $orig_lat + ($dist/69); 


$sql = " 

SELECT `t`.`post_id`, 3956 * 2 * ASIN(SQRT(POWER(SIN((".$orig_lat." - `t`.`lat`) * pi()/180/2), 2) + COS(".$orig_lat." * pi()/180) * COS(`t`.`lat` * pi()/180) * POWER(SIN((".$orig_lon." - `t`.`lng`) * pi()/180/2), 2))) AS `distance` FROM (
    SELECT `post_id`, `lat`, `lng` FROM `x_geodata` WHERE `post_type` = 'some post type' AND `lng` BETWEEN '".$lon1."' AND '".$lon2."' AND `lat` BETWEEN '".$lat1."' AND '".$lat2."' 
) AS `t` HAVING `distance` <= ".$dist." 

"; 

쿼리 검사는 우리가 올바른 포스트 유형을보고 있는지 확인하고 다음 위도와 LNG에 사각형 반경 검사를 수행합니다

다음 유일한 쿼리가이 테이블에서 실행

가되어있다. 반환 된 결과는 원형 반경 확인을 통해 실행됩니다.

내가 찾고있는이 INDEXED 올바르게 얻으려면 CREATE TABLE SQL 또는 UPDATE TABLE SQL 업데이트됩니다.

도움을 주시면 대단히 감사하겠습니다.

편집 : 는이 arnep의 답변에 따라 내 쿼리에 EXPLAIN나요 나는이있어 : MySQL을위한

id select_type table type possible_keys key key_len ref rows Extra 
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 
2 DERIVED zch_geodatastore range post_type post_type 70 NULL 3 Using where 

는하지만 무엇을 의미하는지 아니 생각 ...

+0

'EXPLAIN'은 두 부분으로 나뉩니다. 하나는 외부 선택이고, 두 번째는 내부 선택입니다. inner select는 WHERE 절을 사용하여 의도 한대로 새 인덱스를 사용하고, 3 행을 반환합니다. 외부 선택은 인덱스가없는이 "파생 된"테이블을 사용하지만 걱정하지 마십시오. 모든 행에 대해 계산할 때 인덱스가 필요하지 않습니다. 내부 선택에 대한 자세한 내용은 다른'EXPLAIN'을 수행 할 수 있습니다. btw :'CREATE TABLE'은'lon'을 사용합니다, 당신의'SELECT'는'lng' ...을 혼란스럽게 사용합니다. 그리고 내부 선택은'lat'와'lng'을 반환하지 않습니다 ... 누락 된 someting? – arnep

+0

코드를 업데이트했습니다.표는 lon이 아닌 lng이어야합니다. 내부 쿼리에'lat'와'lng'를 추가했습니다. 이 코드를 올렸을 때 내가 어떻게 그들을 놓쳤는 지 모르겠다. – Brady

답변

1

post_type, latlonWHERE 절에 내가 그에 인덱스를 넣어 추천합니다.

EXPLAIN [QUERY]을 사용하면 색인이 사용되는지 여부와 그로 인해 얻을 수있는 이점을 확인할 수 있습니다.

+0

색인을 어떻게 작성하나요? 다음과 같이 : KEY post_type (post_type, lat, lng)'? – Brady

+0

'ALTER TABLE x_geodata ADD INDEX new_index (post_type, lat, lng); 'MySQL Query Browser 또는 PHPMyAdmin과 같은 도구를 사용하여 인덱스 등을 생성하고 생성 된 SQL 출력을 살펴볼 것을 권장합니다. 또는 mysql.com을 읽어보십시오 : – arnep

+0

은 EXPLAIN을 사용했습니다. 질문 편집을 참조하십시오. – Brady

2

MySQL이 특별한 가지고 SPATIAL 키를 .
참조 : http://dev.mysql.com/tech-resources/articles/4.1/gis-with-mysql.html

그리고에서 인용 : http://dev.mysql.com/doc/refman/5.1/en/create-index.html

의 MyISAM은, 이노, NDB 및 아카이브 스토리지 엔진은 포인트와 기하학 (같은 공간 컬럼을 지원 (섹션 11.17, "공간 확장. "공간 데이터 유형에 대해 설명)

공간 키는 다음과 같습니다.. 단지 MyISAM 테이블에 사용할 수 •
SPATIAL 지정 다른 스토리지 엔진에 대한 INDEX로 인해 오류가 발생합니다.
• 인덱스 열은 NOT NULL이어야합니다.
• MySQL 5.1에서 열 머리말 길이는 금지됩니다. 각 열의 전체 너비가 색인됩니다.

이러한 종류의 질문에 대해서는 https://gis.stackexchange.com/ 특별 포럼 인 것을 알고 계셨습니까?
질문을 올리시기를 권합니다. SELECT 당신의 내면으로

+0

GIS 게시와 관련하여 http://dba.stackexchange.com/에 대해서도 똑같이 말할 수 있습니다. 결국 데이터베이스 질문입니다. 그러나 이것이 3 가지 중 조금이기 때문에 여기에 게시하는 것이 더 적절하다고 생각했습니다. 그러나 관리자가이 게시물을 이동할 필요성을 느낀다면 그렇게하십시오. – Brady

+0

SPATIAL INDEX를 사용하고 있다는 것을 알고 있지만이 테이블이 필요한 간단한 요구 사항에 대한 약간의 OTT가 아닙니까? 게다가 POINT 만 사용하고 있습니다. 그런 다음 공간 데이터 유형의 오버 헤드가 텍스트 표현에서 모든 표현으로의 변환에 너무 많을 수 있습니까? – Brady

+2

@Brady, advice! = critism – Johan

관련 문제