我的表目前維持這樣的:如何將此MySQL表與INDO數據一起使用?
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."
";
查詢檢查,以確保我們正在尋找正確的職位類型,然後做的緯度和經度方半徑檢查。然後返回的結果通過循環半徑檢查運行。
我在找的是更新CREATE TABLE SQL或UPDATE TABLE SQL以正確地得到這個INDEXED。
任何幫助,非常感謝。
編輯: 難道基於arnep回答我的查詢的解釋,我得到了這一點:
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'包含兩個部分:一個是外部選擇,第二個是內部選擇。內部select使用你的新索引,通過使用你的'WHERE'子句,它返回3行。外層選擇使用這個「派生」表,沒有任何索引...但不用擔心:因爲它計算每行的一些東西,所以不需要索引。有關內部選擇的更多信息,您可以在其上執行另一個「EXPLAIN」。 btw:你的'CREATE TABLE'使用'lon',你的'SELECT'使用'lng' ......令人困惑。而你的內心選擇不會返回'lat'和'lng' ...缺少某些東西? – arnep 2011-05-18 09:55:00
我已更新我的代碼。表應該不是lon。我在'lat'和'lng'中添加了內部查詢。當我發佈這些代碼時,不知道我是如何錯過它們的。 – Brady 2011-05-18 10:13:09