Commit acdf2a8b authored by Teodor Sigaev's avatar Teodor Sigaev

Introduce SP-GiST operator class over box.

Patch implements quad-tree over boxes, naive approach of 2D quad tree will not
work for any non-point objects because splitting space on node is not
efficient. The idea of pathc is treating 2D boxes as 4D points, so,
object will not overlap (in 4D space).

The performance tests reveal that this technique especially beneficial
with too much overlapping objects, so called "spaghetti data".

Author: Alexander Lebedev with editorization by Emre Hasegeli and me
parent 87545f54
...@@ -112,6 +112,24 @@ ...@@ -112,6 +112,24 @@
<literal>@&gt;</> <literal>@&gt;</>
</entry> </entry>
</row> </row>
<row>
<entry><literal>box_ops</></entry>
<entry>box</entry>
<entry>
<literal>&lt;&lt;</>
<literal>&amp;&lt;</>
<literal>&amp;&amp;</>
<literal>&amp;&gt;</>
<literal>&gt;&gt;</>
<literal>~=</>
<literal>@&gt;</>
<literal>&lt;@</>
<literal>&amp;&lt;|</>
<literal>&lt;&lt;|</>
<literal>|&gt;&gt;</literal>
<literal>|&amp;&gt;</>
</entry>
</row>
<row> <row>
<entry><literal>text_ops</></entry> <entry><literal>text_ops</></entry>
<entry><type>text</></entry> <entry><type>text</></entry>
......
...@@ -14,8 +14,8 @@ OBJS = acl.o arrayfuncs.o array_expanded.o array_selfuncs.o \ ...@@ -14,8 +14,8 @@ OBJS = acl.o arrayfuncs.o array_expanded.o array_selfuncs.o \
bool.o cash.o char.o date.o datetime.o datum.o dbsize.o domains.o \ bool.o cash.o char.o date.o datetime.o datum.o dbsize.o domains.o \
encode.o enum.o expandeddatum.o \ encode.o enum.o expandeddatum.o \
float.o format_type.o formatting.o genfile.o \ float.o format_type.o formatting.o genfile.o \
geo_ops.o geo_selfuncs.o inet_cidr_ntop.o inet_net_pton.o int.o \ geo_ops.o geo_selfuncs.o geo_spgist.o inet_cidr_ntop.o inet_net_pton.o \
int8.o json.o jsonb.o jsonb_gin.o jsonb_op.o jsonb_util.o \ int.o int8.o json.o jsonb.o jsonb_gin.o jsonb_op.o jsonb_util.o \
jsonfuncs.o like.o lockfuncs.o mac.o misc.o nabstime.o name.o \ jsonfuncs.o like.o lockfuncs.o mac.o misc.o nabstime.o name.o \
network.o network_gist.o network_selfuncs.o \ network.o network_gist.o network_selfuncs.o \
numeric.o numutils.o oid.o oracle_compat.o \ numeric.o numutils.o oid.o oracle_compat.o \
......
This diff is collapsed.
...@@ -832,6 +832,22 @@ DATA(insert ( 3474 3831 3831 8 s 3892 4000 0 )); ...@@ -832,6 +832,22 @@ DATA(insert ( 3474 3831 3831 8 s 3892 4000 0 ));
DATA(insert ( 3474 3831 2283 16 s 3889 4000 0 )); DATA(insert ( 3474 3831 2283 16 s 3889 4000 0 ));
DATA(insert ( 3474 3831 3831 18 s 3882 4000 0 )); DATA(insert ( 3474 3831 3831 18 s 3882 4000 0 ));
/*
* SP-GiST box_ops
*/
DATA(insert ( 5000 603 603 1 s 493 4000 0 ));
DATA(insert ( 5000 603 603 2 s 494 4000 0 ));
DATA(insert ( 5000 603 603 3 s 500 4000 0 ));
DATA(insert ( 5000 603 603 4 s 495 4000 0 ));
DATA(insert ( 5000 603 603 5 s 496 4000 0 ));
DATA(insert ( 5000 603 603 6 s 499 4000 0 ));
DATA(insert ( 5000 603 603 7 s 498 4000 0 ));
DATA(insert ( 5000 603 603 8 s 497 4000 0 ));
DATA(insert ( 5000 603 603 9 s 2571 4000 0 ));
DATA(insert ( 5000 603 603 10 s 2570 4000 0 ));
DATA(insert ( 5000 603 603 11 s 2573 4000 0 ));
DATA(insert ( 5000 603 603 12 s 2572 4000 0 ));
/* /*
* GiST inet_ops * GiST inet_ops
*/ */
......
...@@ -443,6 +443,11 @@ DATA(insert ( 4017 25 25 2 4028 )); ...@@ -443,6 +443,11 @@ DATA(insert ( 4017 25 25 2 4028 ));
DATA(insert ( 4017 25 25 3 4029 )); DATA(insert ( 4017 25 25 3 4029 ));
DATA(insert ( 4017 25 25 4 4030 )); DATA(insert ( 4017 25 25 4 4030 ));
DATA(insert ( 4017 25 25 5 4031 )); DATA(insert ( 4017 25 25 5 4031 ));
DATA(insert ( 5000 603 603 1 5012 ));
DATA(insert ( 5000 603 603 2 5013 ));
DATA(insert ( 5000 603 603 3 5014 ));
DATA(insert ( 5000 603 603 4 5015 ));
DATA(insert ( 5000 603 603 5 5016 ));
/* BRIN opclasses */ /* BRIN opclasses */
/* minmax bytea */ /* minmax bytea */
......
...@@ -228,6 +228,7 @@ DATA(insert ( 403 range_ops PGNSP PGUID 3901 3831 t 0 )); ...@@ -228,6 +228,7 @@ DATA(insert ( 403 range_ops PGNSP PGUID 3901 3831 t 0 ));
DATA(insert ( 405 range_ops PGNSP PGUID 3903 3831 t 0 )); DATA(insert ( 405 range_ops PGNSP PGUID 3903 3831 t 0 ));
DATA(insert ( 783 range_ops PGNSP PGUID 3919 3831 t 0 )); DATA(insert ( 783 range_ops PGNSP PGUID 3919 3831 t 0 ));
DATA(insert ( 4000 range_ops PGNSP PGUID 3474 3831 t 0 )); DATA(insert ( 4000 range_ops PGNSP PGUID 3474 3831 t 0 ));
DATA(insert ( 4000 box_ops PGNSP PGUID 5000 603 t 0 ));
DATA(insert ( 4000 quad_point_ops PGNSP PGUID 4015 600 t 0 )); DATA(insert ( 4000 quad_point_ops PGNSP PGUID 4015 600 t 0 ));
DATA(insert ( 4000 kd_point_ops PGNSP PGUID 4016 600 f 0 )); DATA(insert ( 4000 kd_point_ops PGNSP PGUID 4016 600 f 0 ));
DATA(insert ( 4000 text_ops PGNSP PGUID 4017 25 t 0 )); DATA(insert ( 4000 text_ops PGNSP PGUID 4017 25 t 0 ));
......
...@@ -182,5 +182,6 @@ DATA(insert OID = 4081 ( 3580 uuid_minmax_ops PGNSP PGUID )); ...@@ -182,5 +182,6 @@ DATA(insert OID = 4081 ( 3580 uuid_minmax_ops PGNSP PGUID ));
DATA(insert OID = 4103 ( 3580 range_inclusion_ops PGNSP PGUID )); DATA(insert OID = 4103 ( 3580 range_inclusion_ops PGNSP PGUID ));
DATA(insert OID = 4082 ( 3580 pg_lsn_minmax_ops PGNSP PGUID )); DATA(insert OID = 4082 ( 3580 pg_lsn_minmax_ops PGNSP PGUID ));
DATA(insert OID = 4104 ( 3580 box_inclusion_ops PGNSP PGUID )); DATA(insert OID = 4104 ( 3580 box_inclusion_ops PGNSP PGUID ));
DATA(insert OID = 5000 ( 4000 box_ops PGNSP PGUID ));
#endif /* PG_OPFAMILY_H */ #endif /* PG_OPFAMILY_H */
...@@ -5097,6 +5097,17 @@ DESCR("SP-GiST support for quad tree over range"); ...@@ -5097,6 +5097,17 @@ DESCR("SP-GiST support for quad tree over range");
DATA(insert OID = 3473 ( spg_range_quad_leaf_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 16 "2281 2281" _null_ _null_ _null_ _null_ _null_ spg_range_quad_leaf_consistent _null_ _null_ _null_ )); DATA(insert OID = 3473 ( spg_range_quad_leaf_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 16 "2281 2281" _null_ _null_ _null_ _null_ _null_ spg_range_quad_leaf_consistent _null_ _null_ _null_ ));
DESCR("SP-GiST support for quad tree over range"); DESCR("SP-GiST support for quad tree over range");
DATA(insert OID = 5012 ( spg_box_quad_config PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ _null_ spg_box_quad_config _null_ _null_ _null_ ));
DESCR("SP-GiST support for quad tree over box");
DATA(insert OID = 5013 ( spg_box_quad_choose PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ _null_ spg_box_quad_choose _null_ _null_ _null_ ));
DESCR("SP-GiST support for quad tree over box");
DATA(insert OID = 5014 ( spg_box_quad_picksplit PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ _null_ spg_box_quad_picksplit _null_ _null_ _null_ ));
DESCR("SP-GiST support for quad tree over box");
DATA(insert OID = 5015 ( spg_box_quad_inner_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ _null_ spg_box_quad_inner_consistent _null_ _null_ _null_ ));
DESCR("SP-GiST support for quad tree over box");
DATA(insert OID = 5016 ( spg_box_quad_leaf_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 16 "2281 2281" _null_ _null_ _null_ _null_ _null_ spg_box_quad_leaf_consistent _null_ _null_ _null_ ));
DESCR("SP-GiST support for quad tree over box");
/* replication slots */ /* replication slots */
DATA(insert OID = 3779 ( pg_create_physical_replication_slot PGNSP PGUID 12 1 0 0 0 f f f f t f v u 2 0 2249 "19 16" "{19,16,19,3220}" "{i,i,o,o}" "{slot_name,immediately_reserve,slot_name,xlog_position}" _null_ _null_ pg_create_physical_replication_slot _null_ _null_ _null_ )); DATA(insert OID = 3779 ( pg_create_physical_replication_slot PGNSP PGUID 12 1 0 0 0 f f f f t f v u 2 0 2249 "19 16" "{19,16,19,3220}" "{i,i,o,o}" "{slot_name,immediately_reserve,slot_name,xlog_position}" _null_ _null_ pg_create_physical_replication_slot _null_ _null_ _null_ ));
DESCR("create a physical replication slot"); DESCR("create a physical replication slot");
......
...@@ -426,6 +426,12 @@ extern Datum gist_point_consistent(PG_FUNCTION_ARGS); ...@@ -426,6 +426,12 @@ extern Datum gist_point_consistent(PG_FUNCTION_ARGS);
extern Datum gist_point_distance(PG_FUNCTION_ARGS); extern Datum gist_point_distance(PG_FUNCTION_ARGS);
extern Datum gist_point_fetch(PG_FUNCTION_ARGS); extern Datum gist_point_fetch(PG_FUNCTION_ARGS);
/* utils/adt/geo_spgist.c */
Datum spg_box_quad_config(PG_FUNCTION_ARGS);
Datum spg_box_quad_choose(PG_FUNCTION_ARGS);
Datum spg_box_quad_picksplit(PG_FUNCTION_ARGS);
Datum spg_box_quad_inner_consistent(PG_FUNCTION_ARGS);
Datum spg_box_quad_leaf_consistent(PG_FUNCTION_ARGS);
/* geo_selfuncs.c */ /* geo_selfuncs.c */
extern Datum areasel(PG_FUNCTION_ARGS); extern Datum areasel(PG_FUNCTION_ARGS);
......
...@@ -215,3 +215,243 @@ SELECT '' AS four, height(f1), width(f1) FROM BOX_TBL; ...@@ -215,3 +215,243 @@ SELECT '' AS four, height(f1), width(f1) FROM BOX_TBL;
| 0 | 0 | 0 | 0
(4 rows) (4 rows)
--
-- Test the SP-GiST index
--
CREATE TEMPORARY TABLE box_temp (f1 box);
INSERT INTO box_temp
SELECT box(point(i, i), point(i * 2, i * 2))
FROM generate_series(1, 50) AS i;
CREATE INDEX box_spgist ON box_temp USING spgist (f1);
INSERT INTO box_temp
VALUES (NULL),
('(-0,0)(0,100)'),
('(-3,4.3333333333)(40,1)'),
('(0,100)(0,infinity)'),
('(-infinity,0)(0,infinity)'),
('(-infinity,-infinity)(infinity,infinity)');
SET enable_seqscan = false;
SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)';
f1
------------------
(2,2),(1,1)
(4,4),(2,2)
(6,6),(3,3)
(8,8),(4,4)
(-0,100),(0,0)
(0,inf),(0,100)
(0,inf),(-inf,0)
(7 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)';
QUERY PLAN
----------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 << '(30,40),(10,20)'::box)
(2 rows)
SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)';
f1
------------------
(2,2),(1,1)
(4,4),(2,2)
(6,6),(3,3)
(8,8),(4,4)
(10,10),(5,5)
(-0,100),(0,0)
(0,inf),(0,100)
(0,inf),(-inf,0)
(8 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)';
QUERY PLAN
----------------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 &< '(10,100),(5,4.333334)'::box)
(2 rows)
SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)';
f1
-----------------------
(20,20),(10,10)
(22,22),(11,11)
(24,24),(12,12)
(26,26),(13,13)
(28,28),(14,14)
(30,30),(15,15)
(32,32),(16,16)
(34,34),(17,17)
(36,36),(18,18)
(38,38),(19,19)
(40,40),(20,20)
(42,42),(21,21)
(44,44),(22,22)
(46,46),(23,23)
(48,48),(24,24)
(50,50),(25,25)
(inf,inf),(-inf,-inf)
(17 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)';
QUERY PLAN
----------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 && '(25,30),(15,20)'::box)
(2 rows)
SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)';
f1
-------------------
(80,80),(40,40)
(82,82),(41,41)
(84,84),(42,42)
(86,86),(43,43)
(88,88),(44,44)
(90,90),(45,45)
(92,92),(46,46)
(94,94),(47,47)
(96,96),(48,48)
(98,98),(49,49)
(100,100),(50,50)
(11 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)';
QUERY PLAN
----------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 &> '(45,50),(40,30)'::box)
(2 rows)
SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)';
f1
-------------------
(82,82),(41,41)
(84,84),(42,42)
(86,86),(43,43)
(88,88),(44,44)
(90,90),(45,45)
(92,92),(46,46)
(94,94),(47,47)
(96,96),(48,48)
(98,98),(49,49)
(100,100),(50,50)
(10 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)';
QUERY PLAN
----------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 >> '(40,40),(30,30)'::box)
(2 rows)
SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)';
f1
--------------------------
(2,2),(1,1)
(4,4),(2,2)
(40,4.3333333333),(-3,1)
(3 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)';
QUERY PLAN
----------------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 <<| '(10,100),(5,4.33334)'::box)
(2 rows)
SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)';
f1
--------------------------
(2,2),(1,1)
(4,4),(2,2)
(40,4.3333333333),(-3,1)
(3 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)';
QUERY PLAN
----------------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 &<| '(10,4.3333334),(5,1)'::box)
(2 rows)
SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)';
f1
-------------------
(100,100),(50,50)
(0,inf),(0,100)
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)';
QUERY PLAN
-----------------------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 |&> '(49.99,49.99),(49.99,49.99)'::box)
(2 rows)
SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)';
f1
-------------------
(82,82),(41,41)
(84,84),(42,42)
(86,86),(43,43)
(88,88),(44,44)
(90,90),(45,45)
(92,92),(46,46)
(94,94),(47,47)
(96,96),(48,48)
(98,98),(49,49)
(100,100),(50,50)
(0,inf),(0,100)
(11 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)';
QUERY PLAN
-----------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 |>> '(39,40),(37,38)'::box)
(2 rows)
SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,16)';
f1
-----------------------
(16,16),(8,8)
(18,18),(9,9)
(20,20),(10,10)
(inf,inf),(-inf,-inf)
(4 rows)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,15)';
QUERY PLAN
----------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 @> '(15,15),(10,11)'::box)
(2 rows)
SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)';
f1
-----------------
(30,30),(15,15)
(1 row)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)';
QUERY PLAN
----------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 <@ '(30,35),(10,15)'::box)
(2 rows)
SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)';
f1
-----------------
(40,40),(20,20)
(1 row)
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)';
QUERY PLAN
----------------------------------------------
Index Only Scan using box_spgist on box_temp
Index Cond: (f1 ~= '(40,40),(20,20)'::box)
(2 rows)
RESET enable_seqscan;
DROP INDEX box_spgist;
...@@ -1728,15 +1728,19 @@ ORDER BY 1, 2, 3; ...@@ -1728,15 +1728,19 @@ ORDER BY 1, 2, 3;
4000 | 6 | ~= 4000 | 6 | ~=
4000 | 7 | @> 4000 | 7 | @>
4000 | 8 | <@ 4000 | 8 | <@
4000 | 9 | &<|
4000 | 10 | <<|
4000 | 10 | <^ 4000 | 10 | <^
4000 | 11 | < 4000 | 11 | <
4000 | 11 | >^ 4000 | 11 | >^
4000 | 11 | |>>
4000 | 12 | <= 4000 | 12 | <=
4000 | 12 | |&>
4000 | 14 | >= 4000 | 14 | >=
4000 | 15 | > 4000 | 15 | >
4000 | 16 | @> 4000 | 16 | @>
4000 | 18 | = 4000 | 18 | =
(108 rows) (112 rows)
-- Check that all opclass search operators have selectivity estimators. -- Check that all opclass search operators have selectivity estimators.
-- This is not absolutely required, but it seems a reasonable thing -- This is not absolutely required, but it seems a reasonable thing
......
...@@ -117,3 +117,65 @@ SELECT '' AS one, b1.*, b2.* ...@@ -117,3 +117,65 @@ SELECT '' AS one, b1.*, b2.*
WHERE b1.f1 @> b2.f1 and not b1.f1 ~= b2.f1; WHERE b1.f1 @> b2.f1 and not b1.f1 ~= b2.f1;
SELECT '' AS four, height(f1), width(f1) FROM BOX_TBL; SELECT '' AS four, height(f1), width(f1) FROM BOX_TBL;
--
-- Test the SP-GiST index
--
CREATE TEMPORARY TABLE box_temp (f1 box);
INSERT INTO box_temp
SELECT box(point(i, i), point(i * 2, i * 2))
FROM generate_series(1, 50) AS i;
CREATE INDEX box_spgist ON box_temp USING spgist (f1);
INSERT INTO box_temp
VALUES (NULL),
('(-0,0)(0,100)'),
('(-3,4.3333333333)(40,1)'),
('(0,100)(0,infinity)'),
('(-infinity,0)(0,infinity)'),
('(-infinity,-infinity)(infinity,infinity)');
SET enable_seqscan = false;
SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)';
SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)';
SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)';
SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)';
SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)';
SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)';
SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)';
SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)';
SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)';
SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,16)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,15)';
SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)';
SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)';
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)';
RESET enable_seqscan;
DROP INDEX box_spgist;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment