Невже просторовий просто повільний?


9

У SpatiaLite у мене є кілька тисяч полігонів. Я намагаюся зробити запит "штрихи":

select map1.* from map1,map2
where touches(map1."Geometry",map2."Geometry")

і вау, хіба це НЕМАГО!

Однак якщо я попрошу його зробити лише для однієї посилки в map1, вона працює дуже швидко.

select map1.* from map1,map2
where touches(map1."Geometry",map2."Geometry")
and map1."ROWID" = 753

Я очікую, що перший запит буде працювати повільніше, але він дивно повільний. Він працює дуже швидко в SQLServer, Manifold GIS та PostGIS. Простораціональний просто справді неефективний?


9
Дивіться тут для деяких тестів на швидкість SpatiaLite - це передбачає 200-кратне збільшення швидкості для операції ST_Intersects на великому наборі даних , якщо ви використовуєте індекси!
Сімбамангу

дякую за посилання Fezter. Єдиною проблемою з цього прикладу було те, що йому довелося написати додатковий код SQL, щоб включити обмежувальне поле (і йому довелося змусити подати його конверт). Було б добре, якби наступна версія просторіту просто використала б просторові індекси, які вже є.
ajl

Ласкаво просимо на gis.stackexchange.com! Формат цього веб-сайту передбачає, що розміщені відповіді повинні відповідати на початкове запитання. Відповідаючи на відповідь або коментар, найкраще зробити це коментарем.
Шон

Відповіді:


16

Ні, SpatiaLite не такий повільний, просто потрібно використовувати просторовий індекс. Через обмеження в дизайні SQLite, використання просторового індексу в запиті не настільки непомітне, як у PostGIS.

Ось приклад, модифікований із поварової книги SpatiaLite http://www.gaia-gis.it/spatialite-3.0.0-BETA/spatialite-cookbook/html/neighbours.html

Після створення просторового індексу на ваших наборах даних багатокутника

    SELECT map1.*
      FROM map1, map2
     WHERE ST_Touches(map1.geometry, map2.geometry)
       AND map2.ROWID IN (
           SELECT pkid
             FROM idx_map1_geometry
            WHERE pkid MATCH RTreeIntersects(
                  MbrMinX(map1.geometry),
                  MbrMinY(map1.geometry),
                  MbrMaxX(map1.geometry),
                  MbrMaxY(map1.geometry)));

DavidF: дякую за вашу відповідь. Це однозначно прискорить справи. Це дуже погано, що просторові операції неявно не використовують просторовий індекс. Однак я припускаю, що останній пункт І може бути застосований до будь-якого запиту однієї проблеми. Ви думаєте, що просторит одного дня буде неявно підтримувати просторові індекси?

Я розумію, що питання притаманне архітектурі SQLite. Ви, безумовно, можете розмістити повідомлення в групі SpatiaLite Google із додатковими запитаннями. groups.google.com/forum/?fromgroups#!forum/spatialite-users
DavidF

Зауважте, що останні версії Spatialite реалізують Віртуальний просторовий індекс, і вищевказаний синтаксис більше не працює. Запис WHERE буде переписаний як WHERE map2.ROWID в (SELECT ROWID from SpatialIndex WHERE f_table_name = 'map1' AND search_frame = map1.geometry)
rudivonstaden

4

У книзі Еріка Вестри "Геопросторовий розвиток Пітона" на сторінці 188 видно, що для операції "ЗМІСТ" принаймні просторовий може, можливо, дивно, працювати швидше, ніж MySQL та PostGIS - якщо дотримуватися процедуру просторової індексації.


Не дивно, оскільки прості запити в SQLite на 2 · 3 × швидше, ніж у двигуні MySQL InnoDB.
Michał Leon

3

Я писав про це блог деякий час назад. Див. Http://www.frogmouth.net/blog/?p=23

Міха також написав цікавий блог на цю тему .

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