내 표는 현재이 같은 약자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
는하지만 무엇을 의미하는지 아니 생각 ...
'EXPLAIN'은 두 부분으로 나뉩니다. 하나는 외부 선택이고, 두 번째는 내부 선택입니다. inner select는 WHERE 절을 사용하여 의도 한대로 새 인덱스를 사용하고, 3 행을 반환합니다. 외부 선택은 인덱스가없는이 "파생 된"테이블을 사용하지만 걱정하지 마십시오. 모든 행에 대해 계산할 때 인덱스가 필요하지 않습니다. 내부 선택에 대한 자세한 내용은 다른'EXPLAIN'을 수행 할 수 있습니다. btw :'CREATE TABLE'은'lon'을 사용합니다, 당신의'SELECT'는'lng' ...을 혼란스럽게 사용합니다. 그리고 내부 선택은'lat'와'lng'을 반환하지 않습니다 ... 누락 된 someting? – arnep
코드를 업데이트했습니다.표는 lon이 아닌 lng이어야합니다. 내부 쿼리에'lat'와'lng'를 추가했습니다. 이 코드를 올렸을 때 내가 어떻게 그들을 놓쳤는 지 모르겠다. – Brady