1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Allow GiST distance function to return merely a lower-bound.

The distance function can now set *recheck = false, like index quals. The
executor will then re-check the ORDER BY expressions, and use a queue to
reorder the results on the fly.

This makes it possible to do kNN-searches on polygons and circles, which
don't store the exact value in the index, but just a bounding box.

Alexander Korotkov and me
This commit is contained in:
Heikki Linnakangas
2015-05-15 14:26:51 +03:00
parent ecd222e770
commit 35fcb1b3d0
19 changed files with 699 additions and 40 deletions

View File

@ -372,6 +372,36 @@ SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth
48
(1 row)
SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10;
f1
-------------------------------------------------
((240,359),(240,455),(337,455),(337,359))
((662,163),(662,187),(759,187),(759,163))
((1000,0),(0,1000))
((0,1000),(1000,1000))
((1346,344),(1346,403),(1444,403),(1444,344))
((278,1409),(278,1457),(369,1457),(369,1409))
((907,1156),(907,1201),(948,1201),(948,1156))
((1517,971),(1517,1043),(1594,1043),(1594,971))
((175,1820),(175,1850),(259,1850),(259,1820))
((2424,81),(2424,160),(2424,160),(2424,81))
(10 rows)
SELECT * FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10;
f1
-----------------------------------
<(288.5,407),68.2367203197809>
<(710.5,175),49.9624859269432>
<(323.5,1433),51.4417145903983>
<(927.5,1178.5),30.4384625104489>
<(1395,373.5),57.1948424248201>
<(1555.5,1007),52.7091073724456>
<(217,1835),44.5982062419555>
<(489,2421.5),22.3886131772381>
<(2424,120.5),39.5>
<(751.5,2655),20.4022057631032>
(10 rows)
-- Now check the results from plain indexscan
SET enable_seqscan = OFF;
SET enable_indexscan = ON;
@ -1152,6 +1182,54 @@ SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth
48
(1 row)
EXPLAIN (COSTS OFF)
SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10;
QUERY PLAN
-----------------------------------------------------
Limit
-> Index Scan using ggpolygonind on gpolygon_tbl
Order By: (f1 <-> '(0,0)'::point)
(3 rows)
SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10;
f1
-------------------------------------------------
((240,359),(240,455),(337,455),(337,359))
((662,163),(662,187),(759,187),(759,163))
((1000,0),(0,1000))
((0,1000),(1000,1000))
((1346,344),(1346,403),(1444,403),(1444,344))
((278,1409),(278,1457),(369,1457),(369,1409))
((907,1156),(907,1201),(948,1201),(948,1156))
((1517,971),(1517,1043),(1594,1043),(1594,971))
((175,1820),(175,1850),(259,1850),(259,1820))
((2424,81),(2424,160),(2424,160),(2424,81))
(10 rows)
EXPLAIN (COSTS OFF)
SELECT * FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10;
QUERY PLAN
---------------------------------------------------
Limit
-> Index Scan using ggcircleind on gcircle_tbl
Order By: (f1 <-> '(200,300)'::point)
(3 rows)
SELECT * FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10;
f1
-----------------------------------
<(288.5,407),68.2367203197809>
<(710.5,175),49.9624859269432>
<(323.5,1433),51.4417145903983>
<(927.5,1178.5),30.4384625104489>
<(1395,373.5),57.1948424248201>
<(1555.5,1007),52.7091073724456>
<(217,1835),44.5982062419555>
<(489,2421.5),22.3886131772381>
<(2424,120.5),39.5>
<(751.5,2655),20.4022057631032>
(10 rows)
-- Now check the results from bitmap indexscan
SET enable_seqscan = OFF;
SET enable_indexscan = OFF;

View File

@ -224,6 +224,10 @@ SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth
SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ';
SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10;
SELECT * FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10;
-- Now check the results from plain indexscan
SET enable_seqscan = OFF;
SET enable_indexscan = ON;
@ -437,6 +441,14 @@ EXPLAIN (COSTS OFF)
SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ';
SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St ';
EXPLAIN (COSTS OFF)
SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10;
SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10;
EXPLAIN (COSTS OFF)
SELECT * FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10;
SELECT * FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10;
-- Now check the results from bitmap indexscan
SET enable_seqscan = OFF;
SET enable_indexscan = OFF;