Вопрос
В postgis это ST_GeomFromText
звонить очень дорого?Я спрашиваю в основном потому, что у меня есть часто вызываемый запрос, который пытается найти точку, ближайшую к другой точке, соответствующей некоторым критериям, и которая также находится на определенном расстоянии от этой другой точки, и то, как я ее сейчас написал, делает то же самое ST_GeomFromText
дважды:
$findNearIDMatchStmt = $postconn->prepare(
"SELECT internalid " .
"FROM waypoint " .
"WHERE id = ? AND " .
" category = ? AND ".
" (b.category in (1, 3) OR type like ?) AND ".
" ST_DWithin(point, ST_GeomFromText(?," . SRID .
" ),". SMALL_EPSILON . ") " .
" ORDER BY ST_Distance(point, ST_GeomFromText(?,", SRID .
" )) " .
" LIMIT 1");
Есть ли лучший способ переписать это?
Слегка ОТ:На экране предварительного просмотра все мои подчеркивания отображаются в виде & # 9 5 ;
- Я надеюсь, что это не будет так отражено в посте.
Решение
Я не верю, что ST_GeomFromText ()
особенно дорог, хотя в прошлом я оптимизировал запросы PostGIS
, создав функцию, объявив переменную, а затем присвоив ей результат ST_GeomFromText
для переменной.
Вы пытались проверить план выполнения вашего запроса с различными параметрами, потому что это должно дать вам определенное представление о том, какие биты запроса занимают время? Р>
Я предполагаю, что большая часть времени выполнения будет в вызовах ST_DWithin ()
и ST_Distance ()
, хотя если столбцы id и category не индексируется, то может быть интересно сканировать таблицы.
Другие советы
@Ubiguch
Похоже, что ST_DWithin
использует пространственный индекс, так что это, по-видимому, довольно быстро сокращает количество точек, подлежащих запросу.
navaid=> explain select internalid from waypoint where id != 'KROC' AND ST_DWithin(point, ST_GeomFromText('POINT(-77.6723888888889 43.1188611111111)',4326), 0.05) order by st_distance(point, st_geomfromtext('POINT(-77.6723888888889 43.1188611111111)',4326)) limit 1;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=8.37..8.38 rows=1 width=104)
-> Sort (cost=8.37..8.38 rows=1 width=104)
Sort Key: (st_distance(point, '0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry))
-> Index Scan using waypoint_point_idx on waypoint (cost=0.00..8.36 rows=1 width=104)
Index Cond: (point && '0103000020E61000000100000005000000000000C03B6E53C000000060D0884540000000C03B6E53C0000000409D95454000000020D56753C0000000409D95454000000020D56753C000000060D0884540000000C03B6E53C000000060D0884540'::geometry)
Filter: (((id)::text <> 'KROC'::text) AND (point && '0103000020E61000000100000005000000000000C03B6E53C000000060D0884540000000C03B6E53C0000000409D95454000000020D56753C0000000409D95454000000020D56753C000000060D0884540000000C03B6E53C000000060D0884540'::geometry) AND ('0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry && st_expand(point, 0.05::double precision)) AND (st_distance(point, '0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry) < 0.05::double precision))
(6 rows)
Без order by
и тот limit
, похоже, что типичный запрос возвращает максимум 5-10 путевых точек.Так что мне, вероятно, не стоит беспокоиться о дополнительной стоимости фильтра, который применяется к возвращенным баллам.