Apakah Spatialite Sungguh Lambat?

9

Saya punya beberapa ribu poligon di SpatiaLite. Saya mencoba melakukan kueri "sentuhan":

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

dan wow, apakah ini PERLAHAN!

Namun, jika saya memintanya untuk melakukannya hanya untuk satu paket di map1, itu berjalan sangat cepat.

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

Saya berharap bahwa permintaan pertama akan berjalan lebih lambat, tetapi ini sangat lambat. Ini berjalan sangat cepat dalam SQLServer, Manifold GIS, dan PostGIS. Apakah Spatialite benar-benar tidak efisien?

ajl
sumber
9
Lihat di sini untuk beberapa tes pada kecepatan spasial - ini menunjukkan peningkatan kecepatan 200 kali lipat untuk operasi ST_Intersects pada dataset besar JIKA Anda menggunakan indeks!
Simbamangu
terima kasih untuk tautan Fezter. Satu-satunya masalah dengan contoh itu adalah bahwa ia harus menulis kode SQL tambahan untuk menyertakan kotak pembatas (dan, ia harus memaksanya memasukkannya ke dalam amplop). Akan lebih baik jika versi spasial berikutnya hanya akan menggunakan indeks spasial yang sudah ada.
ajl
Selamat datang di gis.stackexchange.com! Format untuk situs ini menyiratkan bahwa jawaban yang diposting harus menjadi jawaban untuk pertanyaan awal. Saat menanggapi jawaban atau komentar, sebaiknya berikan komentar.
Sean

Jawaban:

16

Tidak, SpatiaLite tidak terlalu lambat, Anda hanya perlu menggunakan indeks spasial. Karena keterbatasan dalam desain SQLite, menggunakan indeks spasial dalam kueri tidak terlihat seperti di PostGIS.

Berikut adalah contoh yang dimodifikasi dari SpatiaLite Cookbook http://www.gaia-gis.it/spatialite-3.0.0-BETA/spatialite-cookbook/html/neighbours.html

Setelah membuat indeks spasial pada set data poligon Anda

    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
sumber
DavidF: terima kasih atas jawaban Anda. Itu pasti akan mempercepat. Sayang sekali bahwa operasi spasial tidak secara implisit menggunakan indeks spasial. Namun, saya kira klausa AND terakhir dapat ditempel pada kueri apa pun yang masalah. Apakah Anda pikir spatialite suatu hari nanti akan mendukung indeks spasial secara implisit?
Pemahaman saya adalah bahwa masalah ini melekat dalam arsitektur SQLite. Anda pasti dapat memposting ke Grup Google SpatiaLite dengan lebih banyak pertanyaan. groups.google.com/forum/?fromgroups#!forum/spatialite-users
DavidF
Perhatikan bahwa versi terbaru Spatialite mengimplementasikan Virtual Spatial Index, dan sintaks di atas tidak lagi berfungsi. Klausa WHERE akan ditulis ulang sebagai WHERE map2.ROWID dalam (SELECT ROWID dari SpatialIndex WHERE f_table_name = 'map1' DAN search_frame = map1.geometry)
rudivonstaden
4

Dalam buku Eric Westra 'Python Geospatial Development' halaman 188 menunjukkan bahwa untuk operasi CONTAINS setidaknya Spatialite dapat, mungkin secara mengejutkan, berjalan lebih cepat daripada MySQL dan PostGIS - jika prosedur pengindeksan spasial yang terlibat diikuti.

John Steedman
sumber
Tidak "mengejutkan", karena query sederhana berjalan sekitar 2 ·· 3 × lebih cepat dalam SQLite daripada yang mereka lakukan di mesin MySQL InnoDB.
Michał Leon