Ist Spatialite wirklich langsam?

9

Ich habe ein paar tausend Polygone in SpatiaLite. Ich versuche eine "Berührungs" -Abfrage durchzuführen:

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

und wow, ist es langsam!

Wenn ich es jedoch auffordere, es nur für ein Paket in map1 zu tun, läuft es sehr schnell.

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

Ich erwarte, dass die erste Abfrage langsamer ausgeführt wird, aber sie ist erstaunlich langsam. Es läuft sehr schnell in SQLServer, Manifold GIS und PostGIS. Ist Spatialite wirklich ineffizient?

ajl
quelle
9
Sehen Sie hier für einige Tests auf der Geschwindigkeit der spatialite - eine für einen ST_Intersects Betrieb 200fache Geschwindigkeit zu erhöhen schlägt auf einem großen Datensatz Wenn Sie Indizes verwenden!
Simbamangu
danke für den Link Fezter. Das einzige Problem mit diesem Beispiel war, dass er zusätzlichen SQL-Code schreiben musste, um einen Begrenzungsrahmen einzuschließen (und er musste den Umschlag zwangsernähren). Es wäre schön, wenn die nächste Version von Spatialite einfach die bereits vorhandenen räumlichen Indizes verwenden würde.
Ajl
Willkommen bei gis.stackexchange.com! Das Format für diese Site impliziert, dass die veröffentlichten Antworten Antworten auf die ursprüngliche Frage sein sollten. Wenn Sie auf eine Antwort oder einen Kommentar antworten, ist es am besten, einen Kommentar daraus zu machen.
Sean

Antworten:

16

Nein, SpatiaLite ist nicht so langsam, Sie müssen nur einen räumlichen Index verwenden. Aufgrund von Einschränkungen im SQLite-Design ist die Verwendung eines räumlichen Index in einer Abfrage nicht so unsichtbar wie in PostGIS.

Hier ist ein Beispiel aus dem SpatiaLite-Kochbuch http://www.gaia-gis.it/spatialite-3.0.0-BETA/spatialite-cookbook/html/neighbours.html

Nach dem Erstellen eines räumlichen Index für Ihre Polygondatensätze

    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
quelle
DavidF: Danke für deine Antwort. Das wird die Dinge definitiv beschleunigen. Es ist schade, dass die räumlichen Operationen den räumlichen Index nicht implizit verwenden. Ich nehme jedoch an, dass die letzte AND-Klausel für jede Abfrage, die ein Problem darstellt, angeheftet werden könnte. Glauben Sie, dass Spatialite eines Tages die räumlichen Indizes implizit unterstützen wird?
Nach meinem Verständnis ist das Problem in der Architektur von SQLite enthalten. Sie können jedoch definitiv weitere Fragen an die SpatiaLite Google-Gruppe senden. groups.google.com/forum/?fromgroups#!forum/spatialite-users
DavidF
Beachten Sie, dass die neuesten Versionen von Spatialite einen virtuellen räumlichen Index implementieren und die obige Syntax nicht mehr funktioniert. Die WHERE-Klausel würde als WHERE map2.ROWID in (SELECT ROWID from SpatialIndex WHERE f_table_name = 'map1' UND search_frame = map1.geometry)
umgeschrieben
4

In Eric Westras Buch 'Python Geospatial Development' auf Seite 188 wird gezeigt, dass für die CONTAINS-Operation zumindest Spatialite möglicherweise überraschenderweise schneller als MySQL und PostGIS ausgeführt werden kann - wenn das betreffende räumliche Indizierungsverfahren befolgt wird.

John Steedman
quelle
Nicht "überraschend", da einfache Abfragen in SQLite etwa 2 ·· 3 × schneller ausgeführt werden als in der MySQL InnoDB-Engine.
Michał Leon
3

Ich habe vor einiger Zeit einen Blog darüber geschrieben. Siehe http://www.frogmouth.net/blog/?p=23

Micha hat auch einen interessanten Blog zu diesem Thema geschrieben .

BradHards
quelle