Czy Spatialite jest naprawdę wolny?

9

Mam kilka tysięcy wielokątów w SpatiaLite. Próbuję wykonać zapytanie „dotyka”:

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

i wow, czy to jest WOLNE!

Jeśli jednak poproszę go o zrobienie tego tylko dla jednej paczki na mapie 1, działa ona bardzo szybko.

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

Oczekuję, że pierwsze zapytanie będzie działało wolniej, ale jest zadziwiająco wolne. Działa bardzo szybko w SQLServer, Manifold GIS i PostGIS. Czy Spatialite jest po prostu naprawdę nieefektywny?

ajl
źródło
9
Zobacz tutaj kilka testów prędkości przestrzennej - sugeruje 200-krotny wzrost prędkości dla operacji ST_Intersects na dużym zbiorze danych JEŻELI używasz indeksów!
Simbamangu,
dzięki za link Fezter. Jedynym problemem z tym przykładem było to, że musiał napisać dodatkowy kod SQL, aby uwzględnić ramkę ograniczającą (i musiał wymusić podanie koperty). Byłoby miło, gdyby następna wersja programu spatialite wykorzystywała już istniejące indeksy przestrzenne.
ajl
Witamy na gis.stackexchange.com! Format tej witryny oznacza, że ​​opublikowane odpowiedzi powinny być odpowiedziami na pierwotne pytanie. Odpowiadając na odpowiedź lub komentarz, najlepiej jest zrobić komentarz.
Sean

Odpowiedzi:

16

Nie, SpatiaLite nie jest tak wolny, wystarczy użyć indeksu przestrzennego. Z powodu ograniczeń w projekcie SQLite użycie indeksu przestrzennego w zapytaniu nie jest tak niewidoczne, jak w PostGIS.

Oto przykład zmodyfikowany ze SpatiaLite Cookbook http://www.gaia-gis.it/spatialite-3.0.0-BETA/spatialite-cookbook/html/neighbours.html

Po utworzeniu indeksu przestrzennego w zestawach danych wielokątów

    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
źródło
DavidF: dzięki za odpowiedź. To zdecydowanie przyspieszy sprawę. Szkoda, że ​​operacje przestrzenne nie używają pośrednio indeksu przestrzennego. Podejrzewam jednak, że ostatnia klauzula AND mogłaby zostać rozwiązana w przypadku każdego pytania, z którego jeden problem. Czy sądzisz, że czasoprzestrzeń pewnego dnia pośrednio wesprze indeksy przestrzenne?
Rozumiem, że problem jest nierozerwalnie związany z architekturą SQLite. Możesz jednak zdecydowanie opublikować post w grupie Google SpatiaLite z dodatkowymi pytaniami. groups.google.com/forum/?fromgroups#!forum/spatialite-users
DavidF
Zauważ, że najnowsze wersje Spatialite implementują Virtual Spatial Index, a powyższa składnia już nie działa. Klauzula WHERE zostanie przepisana jako WHERE map2.ROWID w (WYBIERZ ROWID z SpatialIndex WHERE f_table_name = 'map1' AND search_frame = map1.geometry)
rudivonstaden
4

W książce Erica Westry „Python Geospatial Development” strona 188 pokazuje, że dla operacji ZAWIERA co najmniej Spatialite może, być może, co zaskakujące, działać szybciej niż MySQL i PostGIS - jeśli zastosowana zostanie procedura indeksowania przestrzennego.

John Steedman
źródło
Nie jest „zaskakujące”, ponieważ proste zapytania uruchamiane są o 2 · 3 3 razy szybciej w SQLite niż w silniku MySQL InnoDB.
Michał Leon
3

Pisałem o tym blog już jakiś czas temu. Zobacz http://www.frogmouth.net/blog/?p=23

Micha napisał również ciekawy blog na ten temat .

BradHards
źródło