La spatialisation est-elle vraiment lente?

9

J'ai quelques milliers de polygones dans SpatiaLite. J'essaie de faire une requête "touches":

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

et wow, c'est LENT!

Cependant, si je lui demande de le faire pour une seule parcelle dans map1, cela fonctionne très rapidement.

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

Je m'attends à ce que la première requête s'exécute plus lentement, mais elle est incroyablement lente. Il fonctionne très rapidement dans SQLServer, Manifold GIS et PostGIS. La Spatialite est-elle vraiment vraiment inefficace?

ajl
la source
9
Voir ici pour quelques tests sur la vitesse de la spatialite - cela suggère une augmentation de 200 fois la vitesse pour une opération ST_Intersects sur un grand ensemble de données SI vous utilisez des index!
Simbamangu
merci pour le lien Fezter. Le seul problème avec cet exemple était qu'il devait écrire du code SQL supplémentaire pour inclure une boîte englobante (et, il devait forcer le chargement de l'enveloppe). Ce serait bien si la prochaine version de spatialite utiliserait simplement les index spatiaux qui sont déjà là.
ajl
Bienvenue sur gis.stackexchange.com! Le format de ce site implique que les réponses publiées doivent être des réponses à la question d'origine. Lorsque vous répondez à une réponse ou à un commentaire, il est préférable d'en faire un commentaire.
Sean

Réponses:

16

Non, SpatiaLite n'est pas si lent, il vous suffit d'utiliser un index spatial. En raison des limites de la conception SQLite, l'utilisation d'un index spatial dans une requête n'est pas aussi invisible que dans PostGIS.

Voici un exemple modifié du livre de recettes SpatiaLite http://www.gaia-gis.it/spatialite-3.0.0-BETA/spatialite-cookbook/html/neighbours.html

Après avoir créé un index spatial sur vos ensembles de données de polygone

    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
la source
DavidF: merci pour votre réponse. Cela va certainement accélérer les choses. C'est dommage que les opérations spatiales n'utilisent pas implicitement l'index spatial. Cependant, je suppose que la dernière clause AND pourrait être ajoutée à n'importe quelle question sur un problème. Pensez-vous que la spatialite supportera un jour implicitement les index spatiaux?
Ma compréhension est que le problème est inhérent à l'architecture de SQLite. Vous pouvez certainement poster sur le groupe Google SpatiaLite avec plus de questions. groups.google.com/forum/?fromgroups#!forum/spatialite-users
DavidF
Notez que les dernières versions de Spatialite implémentent un index spatial virtuel et que la syntaxe ci-dessus ne fonctionne plus. La clause WHERE serait réécrite sous la forme WHERE map2.ROWID dans (SELECT ROWID de SpatialIndex WHERE f_table_name = 'map1' AND search_frame = map1.geometry)
rudivonstaden
4

Dans le livre d'Eric Westra `` Python Geospatial Development '', la page 188 montre que pour l'opération CONTAINS, au moins Spatialite peut, peut-être de manière surprenante, fonctionner plus rapidement que MySQL et PostGIS - si la procédure d'indexation spatiale impliquée est suivie.

John Steedman
la source
Ce n'est pas "surprenant", car les requêtes simples s'exécutent environ 2 ·· 3 × plus rapidement dans SQLite que dans le moteur MySQL InnoDB.
Michał Leon
3

J'ai écrit un blog à ce sujet il y a quelque temps. Voir http://www.frogmouth.net/blog/?p=23

Micha a également écrit un blog intéressant sur ce sujet .

BradHards
la source