Как индексировать эту таблицу MySQL для использования с данными GEO? - PullRequest
3 голосов
/ 05 мая 2011

Моя таблица сейчас выглядит так:

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;

Как правильно и эффективно УКАЗАТЬ эту таблицу?

В этой таблице выполняется только один запрос:

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 правильно.

Любая помощь очень ценится.

EDIT: Сделал EXPLAIN по моему запросу на основе ответа 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

Понятия не имею, что это значит, хотя ...

Ответы [ 2 ]

2 голосов
/ 05 мая 2011

MySQL имеет специальные SPATIAL ключи для MySQL.
Смотри: 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, InnoDB, NDB и ARCHIVE поддерживают пространственные столбцы, такие как (POINT и GEOMETRY. (Раздел 11.17, «Пространственные расширения», описывает типы пространственных данных.)

Пространственные ключи:
• Доступно только для таблиц MyISAM. Указание SPATIAL INDEX для других механизмов хранения приводит к ошибке.
• Индексированные столбцы должны иметь значение NOT NULL.
• В MySQL 5.1 длина префикса столбца запрещена. Полная ширина каждого столбца индексируется.

Знаете ли вы, что это специальный https://gis.stackexchange.com/ форум для подобных вопросов,
Я рекомендую вам (дважды) опубликовать свой вопрос там же.

1 голос
/ 17 мая 2011

Поскольку ваше внутреннее SELECT использует post_type, lat и lon в WHERE предложении, я бы порекомендовал поставить индекс для них.

Используйте EXPLAIN [QUERY], чтобы увидеть, используется ли индекс и какую выгоду вы получите от него.

...