[postgis-users] Spatial Index Workings
Paul & Caroline Lewis
paulcaz80 at hotmail.com
Mon Jun 14 06:10:10 PDT 2010
Sorry for the late reply but away from all computers for the weekend.
Anyway, thanks again for your help.
To answer your questions:
PostgreSQL version is 8.4.4 - PostGIS version 1.5
The original queries and explain statements are below:
Also included results from your suggested solutions which do improve runtimes.
Query1 START********************:
SELECT * FROM table1 WHERE ST_DWithin(table1.the_geom,
ST_SetSRID(ST_MakePoint(693230.940102042, 739076.954923132, 115.122), 2157),
5) LIMIT 100;
EXPLAIN PLAN:
"Limit (cost=3406.44..340848.60 rows=1 width=394)"
" -> Bitmap Heap Scan on table1 (cost=3406.44..340848.60 rows=1 width=394)"
" Recheck Cond: (the_geom && '01030000206D08000001000000050000000B0E55E1D32725414CAFEBE8FF8D26410B0E55E1D32725414CAFEBE8138E26410B0E55E1E72725414CAFEBE8138E26410B0E55E1E72725414CAFEBE8FF8D26410B0E55E1D32725414CAFEBE8FF8D2641'::geometry)"
" Filter: (('01010000A06D0800000B0E55E1DD2725414CAFEBE8098E26412B8716D9CEC75C40'::geometry && st_expand(the_geom, 5::double precision)) AND _st_dwithin(the_geom, '01010000A06D0800000B0E55E1DD2725414CAFEBE8098E26412B8716D9CEC75C40'::geometry, 5::double precision))"
" -> Bitmap Index Scan on table1_ind_point (cost=0.00..3406.44 rows=101315 width=0)"
" Index Cond: (the_geom && '01030000206D08000001000000050000000B0E55E1D32725414CAFEBE8FF8D26410B0E55E1D32725414CAFEBE8138E26410B0E55E1E72725414CAFEBE8138E26410B0E55E1E72725414CAFEBE8FF8D26410B0E55E1D32725414CAFEBE8FF8D2641'::geometry)"
Query1 END*********************:
Query2 START*******************:
SELECT * FROM table1 WHERE ST_DWithin(table1.the_geom, (SELECT
table2.the_geom FROM table2 WHERE id = 356), 5) LIMIT 100;
EXPLAIN PLAN:
"Limit (cost=8.27..102.44 rows=100 width=394)"
" InitPlan 1 (returns $0)"
" -> Index Scan using table2_pkey on table2 (cost=0.00..8.27 rows=1 width=32)"
" Index Cond: (id = 356)"
" -> Seq Scan on table1 (cost=0.00..7632345.80 rows=8104993 width=394)"
" Filter: st_dwithin(the_geom, $0, 5::double precision)"
Query2 END**********************:
Query2_Improved START************:
This solution produces the same results as Query1 and Query2, it does use the spatial index and is faster. Query2_Improved = 362ms; Query2 = 4624ms; but is slower than Query1 = 253ms which is understandable as Query1 does not have the table2 overhead.
SELECT * FROM table1 INNER JOIN (SELECT table2.the_geom FROM table2 WHERE id
= 356) AS t2
ON ST_DWithin(table1.the_geom, t2.the_geom, 5)
LIMIT 100;
EXPLAIN PLAN:
"Limit (cost=0.00..541.93 rows=1 width=426)"
" -> Nested Loop (cost=0.00..541.93 rows=1 width=426)"
" Join Filter: ((table2.the_geom && st_expand(table1.the_geom, 5::double precision)) AND _st_dwithin(table1.the_geom, table2.the_geom, 5::double precision))"
" -> Index Scan using table2_pkey on table2 (cost=0.00..8.27 rows=1 width=32)"
" Index Cond: (id = 356)"
" -> Index Scan using table1_ind_point on table1 (cost=0.00..500.72 rows=122 width=394)"
" Index Cond: (table1.the_geom && st_expand(table2.the_geom, 5::double precision))"
Query2_Improved END**************:
Query3 START********************:
SELECT tb1.id, tb1.the_geom
FROM table1 AS tb1
WHERE ST_Within(tb1.the_geom, (
SELECT ST_SetSRID(CAST(ST_MakeBox3D(ST_Translate((
SELECT tb2.the_geom FROM table2 AS tb2 WHERE tb2.id = 356
), -5, -4, -2)
, ST_Translate((
SELECT tb3.the_geom FROM table2 AS tb3 WHERE tb3.id = 356
), 5, 4, 2)) AS geometry), 2157)
)
));
EXPLAIN PLAN:
"Seq Scan on table1 tb1 (cost=16.57..7632362.37 rows=8104993 width=136)"
" Filter: st_within(the_geom, $2)"
" InitPlan 3 (returns $2)"
" -> Result (cost=16.55..16.57 rows=1 width=0)"
" InitPlan 1 (returns $0)"
" -> Index Scan using table2_pkey on table2 tb2 (cost=0.00..8.27 rows=1 width=32)"
" Index Cond: (id = 356)"
" InitPlan 2 (returns $1)"
" -> Index Scan using table2_pkey on table2 tb3 (cost=0.00..8.27 rows=1 width=32)"
" Index Cond: (id = 356)"
Query3 END**********************:
Query3_Improved START************:
This solution produces a much faster result, same output results as Query3 and does us the spatial index. Query3 = 435794ms; Query3_Improved = 9452ms, huge improvement so thanks again.
SELECT tb1.id, tb1.the_geom
FROM table1 AS tb1 INNER JOIN
(SELECT ST_SetSRID(CAST(ST_MakeBox3D(ST_Translate(tb2.the_geom, -5, -4,
-2)), ST_Translate(tb2.the_geom, 5,4,2)) As geometry), 2157) As bgeom FROM
table2 As tb2
WHERE tb2.id = 356) As t2
ON ST_Within(tb1.the_geom, t2.bgeom);
EXPLAIN PLAN:
"Nested Loop (cost=0.01..544.08 rows=41 width=136)"
" Join Filter: _st_within(tb1.the_geom, st_setsrid((st_makebox3d(affine(tb2.the_geom, 1::double precision, 0::double precision, 0::double precision, 0::double precision, 1::double precision, 0::double precision, 0::double precision, 0::double precision, 1::double precision, (-5)::double precision, (-4)::double precision, (-2)::double precision), affine(tb2.the_geom, 1::double precision, 0::double precision, 0::double precision, 0::double precision, 1::double precision, 0::double precision, 0::double precision, 0::double precision, 1::double precision, 5::double precision, 4::double precision, 2::double precision)))::geometry, 2157))"
" -> Index Scan using table2_pkey on table2 tb2 (cost=0.00..8.27 rows=1 width=32)"
" Index Cond: (id = 356)"
" -> Index Scan using table1_ind_point on table1 tb1 (cost=0.01..500.73 rows=122 width=136)"
" Index Cond: (tb1.the_geom && st_setsrid((st_makebox3d(affine(tb2.the_geom, 1::double precision, 0::double precision, 0::double precision, 0::double precision, 1::double precision, 0::double precision, 0::double precision, 0::double precision, 1::double precision, (-5)::double precision, (-4)::double precision, (-2)::double precision), affine(tb2.the_geom, 1::double precision, 0::double precision, 0::double precision, 0::double precision, 1::double precision, 0::double precision, 0::double precision, 0::double precision, 1::double precision, 5::double precision, 4::double precision, 2::double precision)))::geometry, 2157))"
Query3_Improved END***************:
Finally and just to clarify, you say that the Z check is not performed in the ST_Within and ST_DWithin cases. Thus my result set only contains points within the X and Y plane boundaries of the Box3D where some of them could be outside in the Z plane!!! If this is correct can you suggest a solution in PostGIS SQL terms or will postprocessing the results in a seperate manner be required? Will 3D awaremess of situations like this be included in future PostGIS versions.
Anyway thanks again,
Paul
_________________________________________________________________
Hotmail: Trusted email with Microsoft’s powerful SPAM protection.
https://signup.live.com/signup.aspx?id=60969
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20100614/81d0c91e/attachment.html>
More information about the postgis-users
mailing list