SELECT p.GEOMETRY, t.transaction_id
FROM plots AS p, zones AS z
JOIN transactions AS t ON p.property_id = t.property_id
WHERE p.ROWID IN (SELECT ROWID FROM SpatialIndex
WHERE f_table_name='plots' AND search_frame=z.GEOMETRY)
AND st_within(p.GEOMETRY,z.GEOMETRY)
SELECT p.GEOMETRY, t.transaction_id
FROM plots AS p, zones AS z
JOIN transactions AS t ON p.property_id = t.property_id
WHERE p.ROWID IN (SELECT ROWID FROM SpatialIndex
WHERE f_table_name='plots' AND search_frame=z.GEOMETRY)
AND st_within(p.GEOMETRY,z.GEOMETRY)
AND t.prov_code = 3
SELECT A.GEOMETRY, A.transaction_id
FROM ( SELECT p.GEOMETRY, t.transaction_id
FROM plots AS p
JOIN transactions AS t ON p.property_id = t.property_id
WHERE t.prov_code = 3) AS A,
( SELECT * FROM zones
WHERE prov_code = 3) AS B
WHERE st_within(A.GEOMETRY,B.GEOMETRY)
./configure CFLAGS="-DSQLITE_ENABLE_EXPLAIN_COMMENTS"
sudo make install
Hi there,first-off I'd like to kindly thank Marc and Sandro for helping me getting more familiar with some basics of SQL and Spatialite yesterday. As I slowly build the foundations and walls of my house (referring to Sandro's analogy in my previous post), I have come across a specific example which I find puzzling, and I think it would be very pedagogical for me to figure out. I was hoping to get some help on this. My DB contains 3 tables:
- a 'transactions' table with information on real-estate transactions, including the province in which they occur (~1.5M rows).
- a 'plot' table with info on land plots, including their location which is a POINT geography column with Spatial Index (~4.5M rows).
- a 'zones' table containing small disjoint polygons (also spatially indexed), and the province in which they lie (~1.2K rows/polygons).
All transactions describe the sale of a property, and each property lies on a land plot contained in my 'plot' table. I would like to obtain all transactions occurring inside the zones (polygons) for a specific province. I can run a query just fine for the entire DB, but subsetting on a province makes the query impossibly long if I invoke the spatial index.A bit more details:the following query successfully retrieves all transactions occurring inside the polygons for ALL provinces:
SELECT p.GEOMETRY, t.transaction_id
FROM plots AS p, zones AS z
JOIN transactions AS t ON p.property_id = t.property_id
WHERE p.ROWID IN (SELECT ROWID FROM SpatialIndex
WHERE f_table_name='plots' AND search_frame=z.GEOMETRY)
AND st_within(p.GEOMETRY,z.GEOMETRY)This takes ~60 seconds which I think is really reasonable given the size of my DB and that i'm executing the query on a not-too-recent macbook. Now things get tricky when I try to execute the same query but when retaining only the rows in a given province:
SELECT p.GEOMETRY, t.transaction_id
FROM plots AS p, zones AS z
JOIN transactions AS t ON p.property_id = t.property_id
WHERE p.ROWID IN (SELECT ROWID FROM SpatialIndex
WHERE f_table_name='plots' AND search_frame=z.GEOMETRY)
AND st_within(p.GEOMETRY,z.GEOMETRY)
AND t.prov_code = 3The above takes >500 seconds and I'm struggling to grasp why.
Hi there,first-off I'd like to kindly thank Marc and Sandro for helping me getting more familiar with some basics of SQL and Spatialite yesterday. As I slowly build the foundations and walls of my house (referring to Sandro's analogy in my previous post), I have come across a specific example which I find puzzling, and I think it would be very pedagogical for me to figure out. I was hoping to get some help on this. My DB contains 3 tables:
- a 'transactions' table with information on real-estate transactions, including the province in which they occur (~1.5M rows).
- a 'plot' table with info on land plots, including their location which is a POINT geography column with Spatial Index (~4.5M rows).
- a 'zones' table containing small disjoint polygons (also spatially indexed), and the province in which they lie (~1.2K rows/polygons).
All transactions describe the sale of a property, and each property lies on a land plot contained in my 'plot' table. I would like to obtain all transactions occurring inside the zones (polygons) for a specific province. I can run a query just fine for the entire DB, but subsetting on a province makes the query impossibly long if I invoke the spatial index.A bit more details:the following query successfully retrieves all transactions occurring inside the polygons for ALL provinces:
SELECT p.GEOMETRY, t.transaction_id
FROM plots AS p, zones AS z
JOIN transactions AS t ON p.property_id = t.property_id
WHERE p.ROWID IN (SELECT ROWID FROM SpatialIndex
WHERE f_table_name='plots' AND search_frame=z.GEOMETRY)
AND st_within(p.GEOMETRY,z.GEOMETRY)This takes ~60 seconds which I think is really reasonable given the size of my DB and that i'm executing the query on a not-too-recent macbook. Now things get tricky when I try to execute the same query but when retaining only the rows in a given province:
SELECT p.GEOMETRY, t.transaction_id
FROM plots AS p, zones AS z
JOIN transactions AS t ON p.property_id = t.property_id
WHERE p.ROWID IN (SELECT ROWID FROM SpatialIndex
WHERE f_table_name='plots' AND search_frame=z.GEOMETRY)
AND st_within(p.GEOMETRY,z.GEOMETRY)
AND t.prov_code = 3The above takes >500 seconds and I'm struggling to grasp why. Finally, I manage to get reasonable performance (30 seconds) with:
((point_z=33.620000) AND (point_z>2.77 ))
diff explain.before.txt explain.after.txt
21,29c21,29< 20 Column 0 3 9 0 00 r[9]=berlin_dhhn92_2007.point_z< 21 RealAffinity 9 0 0 00< 22 Ne 10 33 9 (BINARY) 55 if r[9]!=r[10] goto 33< 23 Le 12 33 9 (BINARY) 55 if r[9]<=r[12] goto 33< 24 Column 0 4 13 NULL 00 r[13]=berlin_dhhn92_2007.utm_point< 25 Function0 2 13 11 ST_ClosestPoint(2) 02 r[11]=func(r[13..14])< 26 IsNull 11 33 0 00 if r[11]==NULL goto 33< 27 Column 0 4 11 NULL 00 r[11]=berlin_dhhn92_2007.utm_point< 28 Function0 0 11 16 ST_Z(1) 01 r[16]=func(r[11])---> 20 Column 0 4 10 NULL 00 r[10]=berlin_dhhn92_2007.utm_point> 21 Function0 2 10 9 ST_ClosestPoint(2) 02 r[9]=func(r[10..11])> 22 IsNull 9 33 0 00 if r[9]==NULL goto 33> 23 Column 0 3 9 0 00 r[9]=berlin_dhhn92_2007.point_z> 24 RealAffinity 9 0 0 00> 25 Ne 12 33 9 (BINARY) 55 if r[9]!=r[12] goto 33> 26 Le 14 33 9 (BINARY) 55 if r[9]<=r[14] goto 33> 27 Column 0 4 13 NULL 00 r[13]=berlin_dhhn92_2007.utm_point> 28 Function0 0 13 16 ST_Z(1) 01 r[16]=func(r[13])51,58c51,58< 50 Real 0 10 0 33.62 00 r[10]=33.62< 51 Real 0 12 0 2.77 00 r[12]=2.77< 52 Real 0 30 0 24700.552 00 r[30]=24700.552< 53 Real 0 31 0 20674.744 00 r[31]=20674.744< 54 Integer 3068 32 0 00 r[32]=3068< 55 Function0 7 30 28 MakePoint(3) 03 r[28]=func(r[30..32])< 56 Integer 25833 29 0 00 r[29]=25833< 57 Function0 3 28 14 ST_Transform(2) 02 r[14]=func(r[28..29])---> 50 Real 0 30 0 24700.552 00 r[30]=24700.552> 51 Real 0 31 0 20674.744 00 r[31]=20674.744> 52 Integer 3068 32 0 00 r[32]=3068> 53 Function0 7 30 28 MakePoint(3) 03 r[28]=func(r[30..32])> 54 Integer 25833 29 0 00 r[29]=25833> 55 Function0 3 28 11 ST_Transform(2) 02 r[11]=func(r[28..29])> 56 Real 0 12 0 33.62 00 r[12]=33.62> 57 Real 0 14 0 2.77 00 r[14]=2.77
Hi
Read
https://groups.google.com/forum/#!topic/spatialite-users/u8uo6IWg-vE
and try with the unary "+"
SELECT p.GEOMETRY, t.transaction_id
FROM plots AS p, zones AS z
JOIN transactions AS t ON p.property_id = t.property_id
WHERE p.ROWID IN (SELECT ROWID FROM SpatialIndex
WHERE f_table_name='plots' AND search_frame=z.GEOMETRY)
AND st_within(p.GEOMETRY,z.GEOMETRY)
AND +t.prov_code = 3;
It could also be worth trying CROSS JOIN as in
0|0|1|SCAN TABLE zones AS z
0|1|0|SEARCH TABLE plots AS p USING INTEGER PRIMARY KEY (rowid=?)
0|0|0|EXECUTE CORRELATED LIST SUBQUERY 1
1|0|0|SCAN TABLE SpatialIndex VIRTUAL TABLE INDEX 2:
0|2|2|SEARCH TABLE transactions AS t USING AUTOMATIC COVERING INDEX (property_id=?)
0|0|2|SEARCH TABLE transactions AS t USING INDEX prov_ind (prov_code=?)
0|1|0|SEARCH TABLE plots AS p USING INDEX property_ind_plot (property_id=?)
0|2|1|SCAN TABLE zones AS z
0|0|0|EXECUTE CORRELATED LIST SUBQUERY 1
1|0|0|SCAN TABLE SpatialIndex VIRTUAL TABLE INDEX 2:
CREATE TEMPORARY TABLE trans_3 AS
SELECT p.GEOMETRY, t.trans_id
FROM plots AS p
JOIN transactions AS t on p.property_id = t.property_id
WHERE t.prov_code = 3;
CREATE TEMPORARY TABLE zone_3 AS
SELECT * FROM zones
WHERE prov_code = 3;
SELECT t.GEOMETRY, t.trans_id
FROM trans_3 AS t, zone_3 AS z
WHERE t.ROWID IN (
SELECT ROWID
FROM SpatialIndex
WHERE f_table_name='trans_3'
AND search_frame=z.GEOMETRY)
AND st_within(t.GEOMETRY,z.GEOMETRY);
SELECT t.GEOMETRY, t.trans_id
FROM trans_3 AS t,
zone_3 AS z
WHERE st_within(t.GEOMETRY,z.GEOMETRY);