Коли НЕ слід використовувати просторовий індекс?


29

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

13226, 00000, "інтерфейс не підтримується без просторового індексу" // * Причина: Таблиця геометрії не має просторового індексу. // * Дія: Перевірте, що таблиця геометрії, на яку посилається просторовий оператор, має на ній просторовий індекс.

Для мене це має сенс. Ви запускаєте просторовий запит = у вас повинен бути просторовий індекс. Але наскільки я розумію, ні PostGIS, ні SQL Serve цього не вимагають. PostGIS навіть, здається, має функції (_ *, наприклад, _STContains), які ЕКСПЛІКАТНО не використовуватимуть просторовий індекс.

Тож питання: чи є випадки, коли НЕ слід використовувати просторовий індекс ?. Не обов’язково, чи є підхід «візьміть або залиште», тобто це не матиме жодних змін, але де НЕ, використовуючи просторовий індекс, покращить ефективність? Для мене останнє речення є суперечливістю термінів, але в іншому випадку, чому PostGIS надаватиме ці функції?


3
Якщо ви хочете побачити, де індекс робить роботу повільніше в PostGIS SET enable_seqscan = вимкнено. Це змусить PostgreSQL використовувати індекси кожен раз. Порівняйте швидкість з нею.
Шон

Дякуємо, що почали цю тему. Я розливаю інформацію в мережі, намагаючись з'ясувати, чому моя організація (уряд) не використовує просторові (або навіть атрибутні) індекси для своїх класів та таблиць функцій Oracle / sde. Тепер у мене є декілька аргументів, щоб їх викласти так, що мені не доведеться витягувати волосся, чекаючи, коли запит вирішиться.
Майк

Відповіді:


12

мапоголік,

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

Отже, коротше - це не одна функція, так що операція з індексом може бути впорядкована для того, щоб вони відбувалися одразу перед інтенсивнішою просторовою перевіркою.


ура LR1234567. Я думаю, це саме те, що я шукав.
мапоголік

25

Якщо ваш набір даних додається та оновлюється часто, то заяви INSERT, DELETE та UPDATE, які спричиняють перебудову індексу, можуть уповільнити роботу бази даних.

Для масових вставок, таких як завантаження всього набору даних ОСМ у базу даних, може бути швидше скинути індекси та створити їх знову після цього.

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

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

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


3
(+1) Чи виявляю я трохи цинізму в останньому зауваженні? :-)
whuber

Зовсім не ;-) Але відмова / відтворення ретельно відрегульованих індексів є корисною відповіддю на питання "Чому на X було витрачено багато часу на зміни бази даних"?
geographika

Дякую geographica- і я згоден із зауваженням Юбера! ;-) Я розумію, що ви скинете / відключите просторові індекси під час масового завантаження - або всі індекси для цього питання, але ви не можете придумати причину, чому ви коли-небудь робитимете просторовий запит БЕЗ використання просторового індексу? Якщо таблиця досить мала, використання індексу може не змінити - достатньо справедливо - але вибираючи не використовувати індекс ?. Не знаю, я думаю, що я просто більше здивований наявністю функцій
непросторового

2
Якщо таблиця досить невелика і вміщується в пам'яті, використання індексу потребує випадкового доступу до диска, який коштує дорожче, ніж проведення послідовного сканування. wiki.postgresql.org/wiki/…
Sean

2
@mapoholic - _ST_Contains може залишитися від того, коли вам довелося вручну зробити попередній фільтр ваших даних, судячи з old.nabble.com/…
geographika

10

Я думаю, це мається на увазі, але я НЕ використовував би просторовий індекс для запиту, коли у мене був би непросторовий індекс, який я міг би використовувати замість цього. Наприклад, у мене 2113 450 балів, які охоплюють США, завантажені в таблицю. Якби я хотів витягнути всі точки, що знаходилися в штаті Аляска, я міг би або зробити просторовий запит, який використовував індекс GIST на геометричній точці для порівняння з геометрією штату Аляска, АБО, я міг би просто використати поле "state_alpha" у точкових даних (яке також індексується), щоб повернути всі точки, у яких "state_alpha" = 'AK'.

"Де просторова частина цього", запитаєте ви? Ну, якщо мені потрібно зробити додатковий просторовий аналіз на точках Alaska_poats після того, як я їх зберу, швидше зібрати ці геометричні точки, використовуючи спочатку непросторовий запит. Це також означає, що для дійсно великих наборів даних ви отримуєте перевагу від додавання поля пошуку (або таблиці) пошуку. Знову ж таки, я знаю, що це, мабуть, очевидно для всіх алеад, я згадую це лише тому, що в минулому я стикався з глобальними наборами даних, які були просто просторово індексовані, і де загальним запитом було "всі функції в країні". Ми отримали багато ефективності, додавши поле індексованого країни_fips.

Нижче наведено деякі результати з ПОЯСНЕННЯ АНАЛІЗУ, які підтверджують суть. (ПРИМІТКА. Я намагався зробити просторовий запит максимально ефективним, використовуючи запит 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 

велике спасибі за це. Коли це ви можете сказати, може здатися очевидним, але моєю першою думкою було б запустити просторовий запит не лише на атрибут. +1 для цього!
мапоголік

0

Щойно помітив це твердження

Для мене це має сенс. Ви запускаєте просторовий запит = у вас повинен бути просторовий індекс

Для мене це зовсім не має сенсу, і я думаю, що і SQL Server, і Postgis роблять кращу роботу або, принаймні, не турбують вас про деталі продуктивності. Насправді, і SQL Server, і Postgis іноді навіть не використовують просторовий індекс (повернутися до сканування повної таблиці).

Для Oracle ви повинні створити індекс, і тому ви повинні заповнити user_sdo_geom_metadata.

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

У базі даних Oracle опустіть індекс, і ви отримаєте безліч помилок і додатків, які не зможуть використовувати просторові запити, отже, не спрацюють.

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