Intereting Posts
Предложение Hibernate @Where Набор запросов Django-фильтра на «кортежи» значений для нескольких столбцов Практически ли для всех есть проверка подлинности (базы данных)? Какой тип данных столбца я должен использовать для хранения больших объемов текста или html Регрессия логики Python или SQL оптимизировать sql-запросы Получить идентификатор множественной вставки в SQL Server 2008 SQL Trigger не может выполнять INSTEAD OF DELETE, но требуется для столбцов ntext, image Импортировать файл .sql в Access как написать триггер mysql Суммарная продолжительность времени по изменению местоположения Есть ли какая-либо библиотека для представления SQL-запросов в качестве объектов в Java-коде? Проблема с гибернацией: внешний ключ должен иметь одинаковое количество столбцов в качестве ссылочного первичного ключа Таблица базы данных MSMQ v Округление возвращало значения float из базы данных в их «правильные» значения

Как оптимизировать SQL-запрос с вычислением расстояния по долготе и широте?

У меня есть таблица со структурой вроде этого:

table name: shop id_shop int(10) name varchar(200) latitude double longitude double 

И я хотел бы рассчитать расстояние между заданными координатами и координатами, сохраненными в базе данных.

Мой текущий запрос:

 SELECT * FROM `shop` AS `s` WHERE ( ( 6371 * ACOS( SIN( RADIANS( latitude ) ) * SIN( RADIANS( 53.5353010379 ) ) + COS( RADIANS( latitude ) ) * COS( RADIANS( 53.5353010379 ) ) * COS( RADIANS( 14.7984442616 ) - RADIANS( longitude ) ) ) ) <= 25 ) 

плюс некоторые JOIN LEFT для некоторых данных.

Есть ли способ оптимизировать этот запрос? С объединениями требуется около 13 мс.

Мне нужно добавить здесь также некоторые LIMIT и COUNT(*) для общего количества магазинов для разбивки на страницы.

Вот несколько идей, некоторые из которых могут не применяться в зависимости от вашей конкретной ситуации.

  1. Вы можете сделать преобразование широты и долготы в радианы и сохранить это в строке. Это позволит сэкономить затраты на эти вычисления (фактически, стоимость будет начисляться один раз при хранении данных).
  2. Если ваша таблица очень большая, вы можете использовать простой расчет линейного расстояния, а не формулу Haversince, чтобы ограничить результаты, к которым вы применяете формулу Haversince.
  3. Если в таблице есть другие данные, которые будут служить хорошим первым фильтром (страна / регион / и т. Д.), Вы можете применить его в первую очередь.
  4. Вы можете изменить порядок своих соединений, чтобы они были применены после фильтра расстояния, чтобы вы не понесли затраты на соединение на данные, которые не соответствуют требованиям.

Ну, для начала вы можете хранить предварительно рассчитанные данные в базе данных при сохранении широты и долготы. Например, если вы предварительно храните широту и долготу в виде радианов, вам нужно будет только один раз вычислить значения RADIANS (широта) и RADIANS (долгота), когда вы храните каждое местоположение, а не каждый раз, когда вам нужно выполнить расчет расстояния ( вероятно, более одного раза.)

Может быть, немного побриться, сохранив SIN (RADIANS (широта)) и COS (RADIANS (широта)), когда вы впервые заселяете строку …

Я предполагаю, что вы делаете много, много «ближайших вещей к X» с течением времени – это то, что люди обычно делают, когда сталкиваются с этим расчетом, – и предварительное вычисление того, что вы можете, как правило, первое, что нужно попробовать.