¿Es la espacialidad realmente lenta?


9

Tengo un par de miles de polígonos en SpatiaLite. Estoy tratando de hacer una consulta de "toques":

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

y wow, es lento!

Sin embargo, si le pido que solo lo haga por un paquete en map1, se ejecuta muy rápido.

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

Espero que la primera consulta se ejecute más lentamente, pero es increíblemente lenta. Se ejecuta muy rápido en SQLServer, Manifold GIS y PostGIS. ¿Es Spatialite simplemente realmente ineficiente?


99
Vea aquí algunas pruebas sobre la velocidad de la espacialidad: ¡sugiere un aumento de velocidad de 200 veces para una operación ST_Intersects en un conjunto de datos grande SI usa índices!
Simbamangu

gracias por el enlace Fezter. El único problema con ese ejemplo fue que tuvo que escribir código SQL adicional para incluir un cuadro delimitador (y tuvo que forzarlo a alimentar el sobre). Sería bueno si la próxima versión de spaceialite simplemente hiciera uso de los índices espaciales que ya están allí.
ajl

Bienvenido a gis.stackexchange.com! El formato de este sitio implica que las respuestas publicadas deben ser respuestas a la pregunta original. Al responder a una respuesta o comentario, es mejor hacer un comentario.
Sean

Respuestas:


16

No, SpatiaLite no es tan lento, solo necesita usar un índice espacial. Debido a las limitaciones en el diseño de SQLite, el uso de un índice espacial en una consulta no es tan invisible como lo es en PostGIS.

Aquí hay un ejemplo modificado del SpatiaLite Cookbook http://www.gaia-gis.it/spatialite-3.0.0-BETA/spatialite-cookbook/html/neighbours.html

Después de crear un índice espacial en sus conjuntos de datos de polígonos

    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: gracias por tu respuesta. Eso definitivamente acelerará las cosas. Es una pena que las operaciones espaciales no utilicen implícitamente el índice espacial. Sin embargo, supongo que la última cláusula AND podría agregarse a cualquier consulta que se emita. ¿Crees que spaceialite algún día admitirá los índices espaciales implícitamente?

Entiendo que el problema es inherente a la arquitectura de SQLite. Sin embargo, definitivamente puedes publicar en el Grupo SpatiaLite de Google con más preguntas. groups.google.com/forum/?fromgroups#!forum/spatialite-users
DavidF

Tenga en cuenta que las últimas versiones de Spatialite implementan un Índice espacial virtual, y la sintaxis anterior ya no funciona. La cláusula WHERE se volvería a escribir como WHERE map2.ROWID en (SELECT ROWID from SpatialIndex WHERE f_table_name = 'map1' AND search_frame = map1.geometry)
rudivonstaden

4

En el libro de Eric Westra 'Python Geospatial Development', la página 188 muestra que, para la operación CONTAINS, al menos Spatialite puede, quizás sorprendentemente, ejecutarse más rápido que MySQL y PostGIS, si se sigue el procedimiento de indexación espacial involucrado.


No es "sorprendente", ya que las consultas simples se ejecutan aproximadamente 2 ·· 3 veces más rápido en SQLite que en el motor MySQL InnoDB.
Michał Leon el

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.