Мне нужно знать наилучшую практику (наилучшую производительность) для запроса к базе данных для следующего сценария (Mysql):
http://sqlfiddle.com/#!9/72191ca/1
У меня есть «стартовыйitem "(точка" Ключ ", синяя точка, лат: 47.471630, lng: 8.297835) с позицией широта / долгота.В пользовательской таблице есть пользователи (A, B, C и т. Д.) С их положением широты и долготы и их индивидуальными диапазонами в км.
Мне нужно запросить таблицу пользователей, чтобы найти идентификаторы, которые имеютключ в пределах их предопределенных диапазонов / расстояния.
Запрос должен быть оптимизирован - примерно 40 000 пользователей должны быть сопоставлены с позицией «ключ» широта / долгота.
Это текущий запрос, который я использую.Производительность довольно хорошая, но есть ли другое решение для этого, которое может использовать индексы?
DROP TABLE IF EXISTS users;
CREATE TABLE `users` (
`user_id` char(1) NOT NULL,
`lat` decimal(8,5) NOT NULL DEFAULT '0.00000',
`lng` decimal(8,5) DEFAULT '0.00000',
`user_range_km` decimal(10,1) NOT NULL DEFAULT '1.0',
PRIMARY KEY (`user_id`),
KEY `lat` (`lat`,`lng`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `users` (`user_id`, `lat`, `lng`, `user_range_km`) VALUES
('A', '47.46911', '8.29560', '0.4'),
('B', '47.48169', '8.30264', '0.4'),
('C', '47.49261', '8.31598', '2.9');
SELECT h.*, ( 6371 * acos( cos( radians(47.471630) ) * cos( radians( h.lat ) ) * cos( radians( h.lng ) - radians(8.297835) ) + sin( radians(47.471630) ) * sin( radians( h.lat ) ) ) ) AS distance
FROM users h
HAVING distance <= h.user_range_km;
+---------+----------+---------+---------------+------------------+
| user_id | lat | lng | user_range_km | distance |
+---------+----------+---------+---------------+------------------+
| A | 47.46911 | 8.29560 | 0.4 | 0.32671077638732 |
| C | 47.49261 | 8.31598 | 2.9 | 2.7021411331883 |
+---------+----------+---------+---------------+------------------+
В моем примере A и C имеют ключ на определенном расстоянии, поэтому мне нужно получить Aи C из запроса.См. SQL Fiddle