Spatialite è davvero lento?


9

Ho un paio di migliaia di poligoni in SpatiaLite. Sto cercando di fare una query "tocchi":

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

e wow, è LENTO!

Tuttavia, se gli chiedo di farlo solo per un pacco in map1, funziona molto velocemente.

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

Mi aspetto che la prima query verrà eseguita più lentamente, ma è incredibilmente lenta. Funziona molto velocemente in SQL Server, Manifold GIS e PostGIS. Spatialite è davvero inefficiente?


9
Vedi qui per alcuni test sulla velocità della spazialite: suggerisce un aumento della velocità di 200 volte per un'operazione ST_Intersects su un set di dati di grandi dimensioni SE usi gli indici!
Simbamangu,

grazie per il link Fezter. L'unico problema con quell'esempio era che doveva scrivere un codice SQL aggiuntivo per includere un rettangolo di selezione (e, doveva forzarlo a dargli da mangiare la busta). Sarebbe bello se la prossima versione di spatialite usasse semplicemente gli indici spaziali che sono già lì.
Aj

Benvenuto su gis.stackexchange.com! Il formato di questo sito implica che le risposte pubblicate devono essere risposte alla domanda originale. Quando si risponde a una risposta o a un commento, è meglio renderlo un commento.
Sean,

Risposte:


16

No, SpatiaLite non è così lento, devi solo usare un indice spaziale. A causa delle limitazioni nella progettazione di SQLite, l'uso di un indice spaziale in una query non è così invisibile come in PostGIS.

Ecco un esempio modificato dal ricettario SpatiaLite http://www.gaia-gis.it/spatialite-3.0.0-BETA/spatialite-cookbook/html/neighbours.html

Dopo aver creato un indice spaziale sui tuoi set di dati poligonali

    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: grazie per la risposta. Ciò accelererà sicuramente le cose. È un peccato che le operazioni spaziali non utilizzino implicitamente l'indice spaziale. Tuttavia, suppongo che l'ultima clausola AND possa essere applicata a qualsiasi problema di una query. Pensi che un giorno la spazialite supporterà implicitamente gli indici spaziali?

La mia comprensione è che il problema è inerente all'architettura di SQLite. Puoi sicuramente pubblicare post nel gruppo Google SpatiaLite con altre domande. groups.google.com/forum/?fromgroups#!forum/spatialite-users
DavidF

Si noti che le ultime versioni di Spatialite implementano un indice spaziale virtuale e la sintassi precedente non funziona più. La clausola WHERE verrebbe riscritta come WHERE map2.ROWID in (SELECT ROWID da SpatialIndex WHERE f_table_name = 'map1' AND search_frame = map1.geometry)
rudivonstaden

4

Nel libro di Eric Westra 'Python Geospatial Development' la pagina 188 mostra che per l'operazione CONTAINS almeno Spatialite può, forse sorprendentemente, funzionare più velocemente di MySQL e PostGIS - se viene seguita la procedura di indicizzazione spaziale coinvolta.


Non "sorprendentemente", poiché le query semplici vengono eseguite circa 2 ·· 3 volte più velocemente in SQLite rispetto al motore InnoDB di MySQL.
Michał Leon,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.