2014-11-19 18:24:58 +01:00
|
|
|
--
|
|
|
|
-- Test GiST indexes.
|
|
|
|
--
|
|
|
|
-- There are other tests to test different GiST opclasses. This is for
|
|
|
|
-- testing GiST code itself. Vacuuming in particular.
|
|
|
|
create table gist_point_tbl(id int4, p point);
|
|
|
|
create index gist_pointidx on gist_point_tbl using gist(p);
|
|
|
|
-- Insert enough data to create a tree that's a couple of levels deep.
|
|
|
|
insert into gist_point_tbl (id, p)
|
|
|
|
select g, point(g*10, g*10) from generate_series(1, 10000) g;
|
|
|
|
insert into gist_point_tbl (id, p)
|
|
|
|
select g+100000, point(g*10+1, g*10+1) from generate_series(1, 10000) g;
|
|
|
|
-- To test vacuum, delete some entries from all over the index.
|
|
|
|
delete from gist_point_tbl where id % 2 = 1;
|
|
|
|
-- And also delete some concentration of values. (GiST doesn't currently
|
|
|
|
-- attempt to delete pages even when they become empty, but if it did, this
|
|
|
|
-- would exercise it)
|
|
|
|
delete from gist_point_tbl where id < 10000;
|
2015-06-04 22:42:23 +02:00
|
|
|
vacuum analyze gist_point_tbl;
|
2015-03-26 18:12:00 +01:00
|
|
|
--
|
|
|
|
-- Test Index-only plans on GiST indexes
|
|
|
|
--
|
|
|
|
create table gist_tbl (b box, p point, c circle);
|
|
|
|
insert into gist_tbl
|
|
|
|
select box(point(0.05*i, 0.05*i), point(0.05*i, 0.05*i)),
|
|
|
|
point(0.05*i, 0.05*i),
|
|
|
|
circle(point(0.05*i, 0.05*i), 1.0)
|
|
|
|
from generate_series(0,10000) as i;
|
2015-06-04 22:42:23 +02:00
|
|
|
vacuum analyze gist_tbl;
|
2015-03-26 18:12:00 +01:00
|
|
|
set enable_seqscan=off;
|
|
|
|
set enable_bitmapscan=off;
|
|
|
|
set enable_indexonlyscan=on;
|
|
|
|
-- Test index-only scan with point opclass
|
|
|
|
create index gist_tbl_point_index on gist_tbl using gist (p);
|
|
|
|
-- check that the planner chooses an index-only scan
|
|
|
|
explain (costs off)
|
|
|
|
select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5));
|
|
|
|
QUERY PLAN
|
|
|
|
--------------------------------------------------------
|
|
|
|
Index Only Scan using gist_tbl_point_index on gist_tbl
|
|
|
|
Index Cond: (p <@ '(0.5,0.5),(0,0)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
-- execute the same
|
|
|
|
select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5));
|
|
|
|
p
|
|
|
|
-------------
|
|
|
|
(0,0)
|
|
|
|
(0.05,0.05)
|
|
|
|
(0.1,0.1)
|
|
|
|
(0.15,0.15)
|
|
|
|
(0.2,0.2)
|
|
|
|
(0.25,0.25)
|
|
|
|
(0.3,0.3)
|
|
|
|
(0.35,0.35)
|
|
|
|
(0.4,0.4)
|
|
|
|
(0.45,0.45)
|
|
|
|
(0.5,0.5)
|
|
|
|
(11 rows)
|
|
|
|
|
|
|
|
-- Also test an index-only knn-search
|
|
|
|
explain (costs off)
|
|
|
|
select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5))
|
2015-08-25 17:43:37 +02:00
|
|
|
order by p <-> point(0.201, 0.201);
|
2015-03-26 18:12:00 +01:00
|
|
|
QUERY PLAN
|
|
|
|
--------------------------------------------------------
|
|
|
|
Index Only Scan using gist_tbl_point_index on gist_tbl
|
|
|
|
Index Cond: (p <@ '(0.5,0.5),(0,0)'::box)
|
2015-08-25 17:43:37 +02:00
|
|
|
Order By: (p <-> '(0.201,0.201)'::point)
|
2015-03-26 18:12:00 +01:00
|
|
|
(3 rows)
|
|
|
|
|
|
|
|
select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5))
|
2015-08-25 17:43:37 +02:00
|
|
|
order by p <-> point(0.201, 0.201);
|
2015-03-26 18:12:00 +01:00
|
|
|
p
|
|
|
|
-------------
|
|
|
|
(0.2,0.2)
|
|
|
|
(0.25,0.25)
|
|
|
|
(0.15,0.15)
|
|
|
|
(0.3,0.3)
|
|
|
|
(0.1,0.1)
|
|
|
|
(0.35,0.35)
|
|
|
|
(0.05,0.05)
|
|
|
|
(0.4,0.4)
|
2015-08-25 17:43:37 +02:00
|
|
|
(0,0)
|
2015-03-26 18:12:00 +01:00
|
|
|
(0.45,0.45)
|
|
|
|
(0.5,0.5)
|
|
|
|
(11 rows)
|
|
|
|
|
2015-05-22 01:47:48 +02:00
|
|
|
-- Check commuted case as well
|
|
|
|
explain (costs off)
|
|
|
|
select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5))
|
2015-08-25 17:43:37 +02:00
|
|
|
order by point(0.101, 0.101) <-> p;
|
2015-05-22 01:47:48 +02:00
|
|
|
QUERY PLAN
|
|
|
|
--------------------------------------------------------
|
|
|
|
Index Only Scan using gist_tbl_point_index on gist_tbl
|
|
|
|
Index Cond: (p <@ '(0.5,0.5),(0,0)'::box)
|
2015-08-25 17:43:37 +02:00
|
|
|
Order By: (p <-> '(0.101,0.101)'::point)
|
2015-05-22 01:47:48 +02:00
|
|
|
(3 rows)
|
|
|
|
|
|
|
|
select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5))
|
2015-08-25 17:43:37 +02:00
|
|
|
order by point(0.101, 0.101) <-> p;
|
2015-05-22 01:47:48 +02:00
|
|
|
p
|
|
|
|
-------------
|
|
|
|
(0.1,0.1)
|
|
|
|
(0.15,0.15)
|
|
|
|
(0.05,0.05)
|
|
|
|
(0.2,0.2)
|
2015-08-25 17:43:37 +02:00
|
|
|
(0,0)
|
2015-05-22 01:47:48 +02:00
|
|
|
(0.25,0.25)
|
|
|
|
(0.3,0.3)
|
|
|
|
(0.35,0.35)
|
|
|
|
(0.4,0.4)
|
|
|
|
(0.45,0.45)
|
|
|
|
(0.5,0.5)
|
|
|
|
(11 rows)
|
|
|
|
|
2015-03-26 18:12:00 +01:00
|
|
|
drop index gist_tbl_point_index;
|
|
|
|
-- Test index-only scan with box opclass
|
|
|
|
create index gist_tbl_box_index on gist_tbl using gist (b);
|
|
|
|
-- check that the planner chooses an index-only scan
|
|
|
|
explain (costs off)
|
|
|
|
select b from gist_tbl where b <@ box(point(5,5), point(6,6));
|
|
|
|
QUERY PLAN
|
|
|
|
------------------------------------------------------
|
|
|
|
Index Only Scan using gist_tbl_box_index on gist_tbl
|
|
|
|
Index Cond: (b <@ '(6,6),(5,5)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
-- execute the same
|
|
|
|
select b from gist_tbl where b <@ box(point(5,5), point(6,6));
|
|
|
|
b
|
|
|
|
-------------------------
|
|
|
|
(5,5),(5,5)
|
|
|
|
(5.05,5.05),(5.05,5.05)
|
|
|
|
(5.1,5.1),(5.1,5.1)
|
|
|
|
(5.15,5.15),(5.15,5.15)
|
|
|
|
(5.2,5.2),(5.2,5.2)
|
|
|
|
(5.25,5.25),(5.25,5.25)
|
|
|
|
(5.3,5.3),(5.3,5.3)
|
|
|
|
(5.35,5.35),(5.35,5.35)
|
|
|
|
(5.4,5.4),(5.4,5.4)
|
|
|
|
(5.45,5.45),(5.45,5.45)
|
|
|
|
(5.5,5.5),(5.5,5.5)
|
|
|
|
(5.55,5.55),(5.55,5.55)
|
|
|
|
(5.6,5.6),(5.6,5.6)
|
|
|
|
(5.65,5.65),(5.65,5.65)
|
|
|
|
(5.7,5.7),(5.7,5.7)
|
|
|
|
(5.75,5.75),(5.75,5.75)
|
|
|
|
(5.8,5.8),(5.8,5.8)
|
|
|
|
(5.85,5.85),(5.85,5.85)
|
|
|
|
(5.9,5.9),(5.9,5.9)
|
|
|
|
(5.95,5.95),(5.95,5.95)
|
|
|
|
(6,6),(6,6)
|
|
|
|
(21 rows)
|
|
|
|
|
|
|
|
drop index gist_tbl_box_index;
|
|
|
|
-- Test that an index-only scan is not chosen, when the query involves the
|
|
|
|
-- circle column (the circle opclass does not support index-only scans).
|
|
|
|
create index gist_tbl_multi_index on gist_tbl using gist (p, c);
|
|
|
|
explain (costs off)
|
|
|
|
select p, c from gist_tbl
|
|
|
|
where p <@ box(point(5,5), point(6, 6));
|
|
|
|
QUERY PLAN
|
|
|
|
---------------------------------------------------
|
|
|
|
Index Scan using gist_tbl_multi_index on gist_tbl
|
|
|
|
Index Cond: (p <@ '(6,6),(5,5)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
-- execute the same
|
|
|
|
select b, p from gist_tbl
|
|
|
|
where b <@ box(point(4.5, 4.5), point(5.5, 5.5))
|
|
|
|
and p <@ box(point(5,5), point(6, 6));
|
|
|
|
b | p
|
|
|
|
-------------------------+-------------
|
|
|
|
(5,5),(5,5) | (5,5)
|
|
|
|
(5.05,5.05),(5.05,5.05) | (5.05,5.05)
|
|
|
|
(5.1,5.1),(5.1,5.1) | (5.1,5.1)
|
|
|
|
(5.15,5.15),(5.15,5.15) | (5.15,5.15)
|
|
|
|
(5.2,5.2),(5.2,5.2) | (5.2,5.2)
|
|
|
|
(5.25,5.25),(5.25,5.25) | (5.25,5.25)
|
|
|
|
(5.3,5.3),(5.3,5.3) | (5.3,5.3)
|
|
|
|
(5.35,5.35),(5.35,5.35) | (5.35,5.35)
|
|
|
|
(5.4,5.4),(5.4,5.4) | (5.4,5.4)
|
|
|
|
(5.45,5.45),(5.45,5.45) | (5.45,5.45)
|
|
|
|
(5.5,5.5),(5.5,5.5) | (5.5,5.5)
|
|
|
|
(11 rows)
|
|
|
|
|
|
|
|
drop index gist_tbl_multi_index;
|
|
|
|
-- Clean up
|
|
|
|
reset enable_seqscan;
|
|
|
|
reset enable_bitmapscan;
|
|
|
|
reset enable_indexonlyscan;
|
|
|
|
drop table gist_tbl;
|