Spatialite действительно медленный?


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. Spatialite просто действительно неэффективен?


9
Посмотрите здесь некоторые тесты на скорость пространственного объекта - он предлагает увеличение скорости в 200 раз для операции ST_Intersects на большом наборе данных, ЕСЛИ вы используете индексы!
Симбамангу

спасибо за ссылку фезтер. Единственная проблема в этом примере заключалась в том, что он должен был написать дополнительный код SQL, чтобы включить ограничивающий прямоугольник (и он вынужден был принудительно передать ему конверт). Было бы хорошо, если бы следующая версия пространственного объекта просто использовала пространственные индексы, которые уже есть.
апреля

Добро пожаловать на 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: спасибо за ваш ответ. Это определенно ускорит процесс. Жаль, что пространственные операции неявным образом не используют пространственный индекс. Тем не менее, я предполагаю, что последнее предложение AND может быть привязано к любому вопросу, который вызывает одну проблему. Вы думаете, что однажды пространственный объект будет неявно поддерживать пространственные индексы?

Насколько я понимаю, эта проблема присуща архитектуре SQLite. Тем не менее, вы можете отправлять сообщения в группу Google SpatiaLite с большим количеством вопросов. groups.google.com/forum/?fromgroups#!forum/spatialite-users
DavidF

Обратите внимание, что в последних версиях Spatialite реализован виртуальный пространственный индекс, и приведенный выше синтаксис больше не работает. Предложение WHERE будет переписано как WHERE map2.ROWID в (ВЫБЕРИТЕ ROWID из SpatialIndex WHERE f_table_name = 'map1' И search_frame = map1.geometry)
rudivonstaden

4

В книге Эрика Вестры «Python Geospatial Development» на странице 188 показано, что для операции CONTAINS, по меньшей мере, Spatialite может, что удивительно, работать быстрее, чем MySQL и PostGIS, - если соблюдается процедура пространственной индексации.


Неудивительно, что простые запросы в SQLite выполняются примерно в 2 · 3 раза быстрее, чем в движке MySQL InnoDB.
Михал Леон

3

Я написал блог об этом некоторое время назад. Смотрите http://www.frogmouth.net/blog/?p=23

Миха также написал интересный блог на эту тему .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.