У меня есть таблица в базе данных postgres со многими столбцами, среди которых у меня есть:
n_store_object_id integer,
n_latitude decimal,
n_longitude decimal
В настоящее время в таблице около 250 000 строк.
Мне нужно найти записи с ненулевым store_object_id, расположенным на фиксированном расстоянии от заданного местоположения. Для вычисления расстояния у меня есть следующая функция:
CREATE OR REPLACE FUNCTION fn_geo_distance(numeric, numeric, numeric, numeric)
RETURNS numeric AS
$BODY$
declare
lat1d ALIAS for $1;
lon1d ALIAS for $2;
lat2d ALIAS for $3;
lon2d ALIAS for $4;
lat1 DECIMAL := lat1d / 57.29577951;
lon1 DECIMAL := lon1d / 57.29577951;
lat2 DECIMAL := lat2d / 57.29577951;
lon2 DECIMAL := lon2d / 57.29577951;
begin
return 3963.0 * acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon2 - lon1));
end;$BODY$
LANGUAGE plpgsql IMMUTABLE;
Теперь запрос, который мне нужен, прост:
select *
from objects
where n_store_object_id is not null
and fn_geo_distance(51.5, 0, n_latitude, n_longitude) <= 20
Это занимает довольно много времени - и когда я "объясняю" этот запрос, я вижу полное сканирование таблицы. Справедливо. Поэтому я создаю индекс для этих трех столбцов:
create index idx_object_location on objects(n_store_object_id, n_latitude, n_longitude)
Я перезапустил запрос выше - и это все еще занимает много времени. «Объяснение» показывает, что вновь созданный индекс не используется. Я что-то пропустил? Почему он не используется и как я могу заставить двигатель использовать его? О, и в первую очередь, поможет ли этот индекс?
Спасибо!