Просторовий індекс PostgreSQL / PostGIS - немає прискорення


15

У мене є просторова таблиця в базі даних PostgreSQL / PostGIS. Кожен рядок у ньому являє собою Полігон. Він має таку форму:

+----+--------+
|gid |   way  |
+----+--------+
|241 | 01030..|

Геометричний стовпчик - "шлях", який містить геометрію для багатокутника. У WKT це: POLYGON (('....')). Я виконую багато запитів ST_Contains в цій таблиці, щоб перевірити, чи містяться два багатокутники один в одному, наприклад:

Select ST_Contains(a.way, b.way) From table AS a, table AS b Where a.gid = 15 And b.gid = 16

Мені було цікаво, як пришвидшити цей запит, і додав просторовий індекс на стіл:

CREATE INDEX table_way_gist ON table USING gist(way);

Але насправді я не бачу швидкості. Я створюю індекс ПІСЛЯ я заповнював таблицю усіма багатокутниками, перш ніж я виконувати запити ST_Contains. Чи слід додавати індекс перед заповненням таблиці? Чи є в таблиці особливі вимоги до роботи з індексом? Проекція (сітка) шляху геометричного стовпчика встановлена ​​на 900913.

Я використовую: psql (PostgreSQL) 9.1.4 / POSTGIS = "1.5.3"

Відповіді:


16

Найефективніший індекс для запиту, висловленого у вашому запитанні, - індекс на gid, оскільки це єдиний стовпець, який з’являється у виразі a

 CREATE INDEX table_gid ON table (gid);

Ви можете сміливо опускати індекс суті, оскільки він займе лише простір і повільно вставить / оновить / видалить вниз.

Довге пояснення

Як я вже сказав, найефективнішим показником у вашому випадку є індекс на gid, оскільки він дозволить db-двигуну швидше отримувати рядки (пошук зазвичай є найповільнішою частиною процесу). Після цього, ймовірно, буде краще обчислити результат

  ST_Contains(a.way, b.way)

експресія, не дивлячись на індекс. Причина полягає в тому, що планувальник запитів, ймовірно, оцінить, що додаткові витрати на пошук індексу суті обох стовпців порівняно з пошуком значень a.way та b.way безпосередньо не варті зусиль, оскільки загальна кількість рядків шукати вгору це, мабуть, дуже мало, особливо якщо індекс унікальний.

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


Це робить для мене питання більш зрозумілим. Я спробую. Отже, якщо я поклав запит ST_Contains () у пункт WHERE, просторовий індекс насправді повинен бути корисним? Я думаю, що мені доведеться реорганізувати свій сценарій для виклику ST_Contains в рамках пункту WHERE. На даний момент я перебираю всі полігони і завжди перевіряю два з них окремо.
MichiMichbeck

?? ти кажеш, що просторовий індекс сповільнює ситуацію? Це для мене нове, адже там, де я працюю, ми маємо просторові індекси для кожної окремої таблиці, і мені цікаво, чи це погана практика
Luffydude

13

Як сказали unicoletti , індекс суті в стовпці з геометрії буде працювати лише в тому випадку, якщо ви використовуєте ST_Contains () у виразі WHERE.

Наприклад, якщо ви хочете знати всі багатокутники, які містять один одного, ви можете використовувати щось подібне:

SELECT a.gid, b.gid
FROM table AS a, table as b
WHERE a.gid != b.gid and ST_Contains(a.way, b.way)

У цьому випадку, залежно від розміру вашої таблиці та складності вашої геометрії, індекс суті повинен забезпечити значну швидкість, оскільки ST_Contains почнеться з фільтрації полігонів шляхом порівняння їх граничних коробок, перш ніж реально перевірити їх повну геометрію. Невелике пояснення ви можете побачити в підручнику OpenGeo .


Так, я бачу, мені потрібно, щоб цей запит включав тест межі індексу. Thx Олександре. (Я відзначу unicoletti як рішення, оскільки він був швидким і
вирішив
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.