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.