Когда НЕ следует использовать пространственный индекс?

29

Я спрашиваю об этом, потому что я в основном работал с Oracle, но в течение прошлого года я удваивался с PostGIS и SQLServer 2008. Большинство пространственных функций в Oracle не будут работать без пространственного индекса, возвращающего ошибку ORA-13226:

13226, 00000, «интерфейс не поддерживается без пространственного индекса» // * Причина: таблица геометрии не имеет пространственного индекса. // * Действие: Убедитесь, что в таблице геометрии, на которую ссылается пространственный оператор, есть пространственный индекс.

Для меня это имеет смысл. Вы запускаете пространственный запрос = у вас должен быть пространственный индекс. Но, насколько я понимаю, ни PostGIS, ни SQL Serve не требуют этого. Кажется, в PostGIS даже есть функции (_ * например _STContains), которые EXPLICITLY не будут использовать пространственный индекс.

Итак, вопрос в том, есть ли случаи, когда вам НЕ следует использовать пространственный индекс? Не обязательно, является ли подход «возьми или оставь это», то есть он не будет иметь никакого значения, но где НЕ использование пространственного индекса будет влиять на производительность? Для меня последнее предложение является противоречием в терминах, но в противном случае, почему PostGIS будет предоставлять эти функции?

mapoholic
источник
3
Если вы хотите увидеть, где индекс замедляет работу, в PostGIS SET enable_seqscan = off. Это заставит PostgreSQL каждый раз использовать индексы. Сравните скорости с этим на.
Шон
Спасибо за начало этой темы. Я пролил информацию в сети, пытаясь выяснить, почему моя организация (правительство) не использует пространственные (или даже атрибутные) индексы в своих классах и таблицах объектов oracle / sde. Теперь у меня есть несколько аргументов, чтобы представить их, так что мне не нужно выдергивать волосы в ожидании решения вопроса.
Майк

Ответы:

12

mapoholic,

Вообще говоря, нет причин делать пространственный запрос без пространственного индекса, если вы не имеете дело с действительно маленькими таблицами. Тем не менее, вы должны использовать ST_, который не использует индекс, но имеет операторы && indexable блоки короткого замыкания. функции, начинающиеся с _ST, не предназначены для использования конечными пользователями. Причина, по которой они существуют, заключается в том, что они должны. Пространственные индексы PostGIS используют встраивание SQL для принудительного использования индекса - _ST обычно выполняется GEOS, а && - это индекс, который может быть переупорядочен. Таким образом, _ST действительно является артефактом реализации.

Короче говоря, это не одна функция, так что операция индекса может быть переупорядочена так, чтобы происходить сразу перед более интенсивной пространственной проверкой.

LR1234567
источник
ура LR1234567. Я думаю, что это то, что я искал.
Mapoholic
25

Если ваш набор данных часто добавляется и обновляется, то операторы INSERT, DELETE и UPDATE, которые приводят к перестройке индекса, могут замедлить работу базы данных.

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

Если более эффективно игнорировать индекс (например, таблица достаточно мала для загрузки в память), процессор запросов к базе данных должен делать это автоматически.

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

Наконец, если вы хотите значительно повысить производительность запросов и отображений карт, вы можете отложить создание индексов до подходящего момента в разработке системы ...

geographika
источник
3
(+1) Я обнаружил небольшой цинизм в этом последнем замечании? :-)
whuber
Вовсе нет ;-) Но удаление / воссоздание тщательно настроенных индексов является полезным ответом на вопрос: «Почему X потратил много времени на изменения базы данных»?
география
Спасибо, география, и я согласен с замечанием Уубера! ;-) Я понимаю, что вы бы сбросили / отключили пространственные индексы при массовой загрузке - или все индексы по этому вопросу, но вы не можете придумать причину, по которой вы бы когда-либо делали пространственный запрос БЕЗ использования пространственного индекса? Если таблица достаточно мала, использование индекса может не иметь значения - достаточно справедливо - но решение не использовать индекс ?. Не знаю, я думаю, я просто больше озадачен существованием функций непространственного индекса PostGIS ...
mapoholic
2
Если таблица достаточно мала и умещается в памяти, использование индекса требует произвольного доступа к диску, который обходится дороже, чем последовательное сканирование. wiki.postgresql.org/wiki/…
Шон,
2
@mapoholic - _ST_Contains можно оставить с того момента, когда вам нужно было вручную выполнить предварительный фильтр ваших данных, судя по old.nabble.com/…
geographika
10

Я думаю, что это подразумевается, но я бы НЕ использовал пространственный индекс для запроса, когда у меня был непространственный индекс, который я мог бы использовать вместо этого. Например, у меня есть 2113450 точек, которые охватывают Соединенные Штаты, загруженные в таблицу. Если бы я хотел вытянуть все точки, которые находились в штате Аляска, я мог бы либо выполнить пространственный запрос, который использовал индекс GIST для геометрии точек, чтобы сравнить с геометрией штата Аляска, ИЛИ, я мог бы просто использовать поле "state_alpha" в данных точек (которое также индексируется), чтобы вернуть все точки, которые имеют "state_alpha" = 'AK'.

«Где пространственная часть этого», спросите вы? Что ж, если после того, как я соберу их, мне понадобится выполнить дополнительный пространственный анализ точек Alaska_points, быстрее собрать эти точечные геометрии, используя сначала непространственный запрос. Это также означает, что для действительно больших наборов данных вы получаете выгоду от добавления поля поиска (или таблицы). Опять же, я знаю, что это, вероятно, очевидно для всех, я упоминаю об этом только потому, что сталкивался с этим в прошлом с глобальными наборами данных, которые были только пространственно проиндексированы, и где общим запросом были «все функции в стране». Мы добились большой производительности, добавив индексированное поле country_fips.

Ниже приведены некоторые результаты EXPLAIN ANALYZE, которые подтверждают это. (ПРИМЕЧАНИЕ. Я попытался сделать пространственный запрос как можно более эффективным с помощью запроса BBOX. Использование контуров состояния сделало бы его медленнее.)

# explain analyze select count(*) from gnis_names where state_alpha = 'AK';
Aggregate  (cost=57359.45..57359.46 rows=1 width=0) (actual time=76.606.. 76.607 rows=1 loops=1)
<snip>
Total runtime: 76.676 ms

# explain analyze select count(*) from gnis_names where the_geom && GeomFromText('POLYGON((-179.14734 51.219862,-179.14734 71.3525606439998,179.77847 71.3525606439998,179.77847 51.219862,-179.14734 51.219862))',4326);
Aggregate  (cost=27699.86..27699.87 rows=1 width=0) (actual time=86.523..86.524 rows=1 loops=1)
<snip>
Total runtime: 86.584 ms 
lagerratrobe
источник
Большое спасибо за это. Когда вы это говорите, это может показаться очевидным, но моей первой мыслью было бы выполнить пространственный запрос, а не только атрибут. +1 за это!
Мапоголик
0

Просто заметил это утверждение

Для меня это имеет смысл. Вы запускаете пространственный запрос = у вас должен быть пространственный индекс

Для меня это совсем не имеет смысла, и я думаю, что и SQL Server, и Postgis работают лучше или, по крайней мере, не беспокоят вас деталями производительности. На самом деле, и SQL Server, и Postgis иногда даже не используют пространственный индекс вообще (возвращаются к полному сканированию таблицы).

Для Oracle вы должны создать индекс и, следовательно, вы должны заполнить user_sdo_geom_metadata.

Просто сравнивая это с алфавитно-цифровыми индексами, они присутствуют по соображениям производительности, ваш оператор SQL должен работать с ним и без него.

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

user2192239
источник