\i :regdir/core/regress_lots_of_points.sql
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
mat := regexp_matches(exp, ' *(?:-> *)?(.*Scan)');
IF mat IS NOT NULL THEN
ret := array_append(ret, mat[1]);
END IF;
END LOOP;
RETURN array_to_string(ret,',');
END;
$$;
CREATE INDEX quick_gist on test using gist (the_geom);
set enable_indexscan = off;
set enable_bitmapscan = off;
set enable_seqscan = on;
SELECT 'scan_idx', qnodes('select * from test where the_geom && ST_MakePoint(0,0)');
select num,ST_astext(the_geom) from test where the_geom && 'BOX3D(125 125,135 135)'::box3d order by num;
set enable_indexscan = on;
set enable_bitmapscan = off;
set enable_seqscan = off;
SELECT 'scan_seq', qnodes('select * from test where the_geom && ST_MakePoint(0,0)');
select num,ST_astext(the_geom) from test where the_geom && 'BOX3D(125 125,135 135)'::box3d order by num;
CREATE FUNCTION estimate_error(qry text, tol int)
RETURNS text
LANGUAGE 'plpgsql' VOLATILE AS $$
DECLARE
anl TEXT := '';
err INT;
est INT;
act INT;
mat TEXT[];
anl_tmp TEXT;
r record;
BEGIN
for r in EXECUTE 'EXPLAIN ANALYZE ' || qry
LOOP
anl_tmp = r;
anl = anl || anl_tmp;
end loop;
SELECT regexp_matches(anl, ' rows=([0-9]*) .* rows=([0-9]*) ')
INTO mat;
est := mat[1];
act := mat[2];
err = abs(est-act);
RETURN act || '+=' || tol || ':' || coalesce(
nullif((err < tol)::text,'false'),
'false:'||err::text
);
END;
$$;
CREATE TABLE sample_queries AS
SELECT 1 as id, 5 as tol, 'ST_MakeEnvelope(125,125,135,135)' as box
UNION ALL
SELECT 2, 60, 'ST_MakeEnvelope(0,0,135,135)'
UNION ALL
SELECT 3, 500, 'ST_MakeEnvelope(0,0,500,500)'
UNION ALL
SELECT 4, 600, 'ST_MakeEnvelope(0,0,1000,1000)'
;
ALTER TABLE test ALTER COLUMN the_geom SET STATISTICS 10000;
ANALYZE test;
SELECT estimate_error(
'select num from test where the_geom && ' || box, tol )
FROM sample_queries ORDER BY id;
CREATE INDEX expressional_gist on test using gist ( st_centroid(the_geom) );
ANALYZE test;
SELECT 'expr', estimate_error(
'select num from test where st_centroid(the_geom) && ' || box, tol )
FROM sample_queries ORDER BY id;
DROP TABLE test;
DROP TABLE sample_queries;
DROP FUNCTION estimate_error(text, int);
DROP FUNCTION qnodes(text);
set enable_indexscan = on;
set enable_bitmapscan = on;
set enable_seqscan = on;
select '_st_sortablehash', _ST_SortableHash('POINT(0 0)'), _ST_SortableHash('SRID=4326;POINT(0 0)'), _ST_SortableHash('SRID=3857;POINT(0 0)');