File: knn.sql

package info (click to toggle)
postgis 2.3.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 58,660 kB
  • ctags: 10,181
  • sloc: ansic: 132,858; sql: 131,148; xml: 46,460; sh: 4,832; perl: 4,476; makefile: 2,749; python: 1,198; yacc: 442; lex: 131
file content (100 lines) | stat: -rw-r--r-- 3,508 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
CREATE OR REPLACE FUNCTION qnodes(q text) RETURNS text
LANGUAGE 'plpgsql' AS
$$
DECLARE
  exp TEXT;
  mat TEXT[];
  ret TEXT[];
BEGIN
  FOR exp IN EXECUTE 'EXPLAIN ' || q
  LOOP
    --RAISE NOTICE 'EXP: %', exp;
    mat := regexp_matches(exp, ' *(?:-> *)?(.*Scan)');
    --RAISE NOTICE 'MAT: %', mat;
    IF mat IS NOT NULL THEN
      ret := array_append(ret, mat[1]);
    END IF;
    --RAISE NOTICE 'RET: %', ret;
  END LOOP;
  RETURN array_to_string(ret,',');
END;
$$;

\i regress_lots_of_points.sql

-- Index-supported KNN query

CREATE INDEX test_gist_2d on test using gist (the_geom);

SELECT '<-> idx', qnodes('select * from test order by the_geom <-> ST_MakePoint(0,0) LIMIT 1');
SELECT '<-> res1',num,
  (the_geom <-> 'POINT(2.5 2.5)'::geometry)::numeric(10,2),
  ST_astext(the_geom) from test
  order by the_geom <-> 'POINT(2.5 2.5)'::geometry LIMIT 1;

-- Full table extent: BOX(0.0439142361 0.0197799355,999.955261 999.993652)
SELECT '<#> idx', qnodes('select * from test order by the_geom <#> ST_MakePoint(0,0) LIMIT 1');
SELECT '<#> res1',num,
  (the_geom <#> 'LINESTRING(1000 0,1005 5)'::geometry)::numeric(10,2),
  ST_astext(the_geom) from test
  order by the_geom <#> 'LINESTRING(1000 0,1005 5)'::geometry LIMIT 1;

-- Index-supported nd-KNN query

DROP INDEX test_gist_2d;

UPDATE test set the_geom = ST_MakePoint(
    ST_X(the_geom), ST_Y(the_geom),
    num, -num);

SELECT '<<->> seq', qnodes('select * from test order by the_geom <<->> ST_MakePoint(0,0)');

CREATE INDEX test_gist_nd on test using gist (the_geom gist_geometry_ops_nd);

ANALYZE test;

--  EXT       X                Y          Z        M
-- min    0.0439142361 |   0.0197799355|     1| -50000
-- max  999.955261     | 999.993652    | 50000|     -1
--SELECT min(st_x(the_geom)) as minx, min(st_y(the_geom)) as miny,
--       min(st_z(the_geom)) as minz, min(st_m(the_geom)) as minm,
--       max(st_x(the_geom)) as maxx, max(st_y(the_geom)) as maxy,
--       max(st_z(the_geom)) as maxz, max(st_m(the_geom)) as maxm
--FROM test;


SELECT '<<->> idx', qnodes('select * from test order by the_geom <<->> ST_MakePoint(0,0) LIMIT 1');
SELECT '<<->> res1',num,
  (the_geom <<->> 'LINESTRING(0 0,5 5)'::geometry)::numeric(10,2),
  ST_astext(the_geom) from test
  order by the_geom <<->> 'LINESTRING(0 0,5 5)'::geometry LIMIT 1;
SELECT '<<->> res2',num,
  (the_geom <<->> 'POINT(95 23 25024 -25025)'::geometry)::numeric(10,2),
  ST_astext(the_geom) from test
  order by the_geom <<->> 'POINT(95 23 25024 -25025)'::geometry LIMIT 1;
SELECT '<<->> res3',num,
  (the_geom <<->> 'POINT(631 729 25023 -25022)'::geometry)::numeric(10,2),
  ST_astext(the_geom) from test
  order by the_geom <<->> 'POINT(631 729 25023 -25022)'::geometry LIMIT 1;


-- Cleanup

DROP FUNCTION qnodes(text);

DROP TABLE test;

-- nd box centroid distance  <<->>

select '<<->> ndcd1', 'LINESTRING(0 0,0 10,10 10)'::geometry <<->>
                'LINESTRING(6 2,6 8)'::geometry; -- 1
select '<<->> ndcd2', 'LINESTRING(0 0,0 10,10 10)'::geometry <<->>
                'LINESTRING(11 0,19 10)'::geometry; -- 10
select '<<->> ndcd3', 'POINTM(0 0 0)'::geometry <<->>
                'POINTM(0 0 5)'::geometry; -- 5
select '<<->> ndcd4', 'POINTZ(0 0 15)'::geometry <<->>
                'POINTZ(0 0 10)'::geometry; -- 5
select '<<->> ndcd5', 'POINTZM(1 2 3 4)'::geometry <<->>
                'POINTZM(2 3 4 5)'::geometry; -- 2
select '<<->> ndcd6', 'POINTZM(9 9 3 4)'::geometry <<->>
                'POINT(9 8)'::geometry; -- 1, higher dimensions overlapping