11CREATE EXTENSION aqo;
2+ -- Utility tool. Allow to filter system-dependent strings from an explain output.
3+ CREATE OR REPLACE FUNCTION expln(query_string text) RETURNS SETOF text AS $$
4+ BEGIN
5+ RETURN QUERY
6+ EXECUTE format('%s', query_string);
7+ RETURN;
8+ END;
9+ $$ LANGUAGE PLPGSQL;
210SET aqo.join_threshold = 0;
311SET aqo.mode = 'learn';
412SET aqo.show_details = 'on';
@@ -35,8 +43,8 @@ EXPLAIN (COSTS OFF)
3543(11 rows)
3644
3745SELECT str FROM expln('
38- EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
39- SELECT * FROM t GROUP BY (x) HAVING x > 3;
46+ EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
47+ SELECT * FROM t GROUP BY (x) HAVING x > 3;
4048') AS str WHERE str NOT LIKE '%Memory Usage%';
4149 str
4250-----------------------------------------------
@@ -485,17 +493,6 @@ SELECT * FROM
485493-- any prediction on number of fetched tuples.
486494-- So, if selectivity was wrong we could make bad choice of Scan operation.
487495-- For example, we could choose suboptimal index.
488- --
489- -- Returns string-by-string explain of a query. Made for removing some strings
490- -- from the explain output.
491- --
492- CREATE OR REPLACE FUNCTION expln(query_string text) RETURNS SETOF text AS $$
493- BEGIN
494- RETURN QUERY
495- EXECUTE format('EXPLAIN (ANALYZE, VERBOSE, COSTS OFF, TIMING OFF, SUMMARY OFF) %s', query_string);
496- RETURN;
497- END;
498- $$ LANGUAGE PLPGSQL;
499496-- Turn off statistics gathering for simple demonstration of filtering problem.
500497ALTER TABLE t SET (autovacuum_enabled = 'false');
501498CREATE INDEX ind1 ON t(x);
@@ -531,10 +528,11 @@ SELECT count(*) FROM t WHERE x < 3 AND mod(x,3) = 1;
531528 50
532529(1 row)
533530
534- SELECT str AS result
535- FROM expln('SELECT count(*) FROM t WHERE x < 3 AND mod(x,3) = 1') AS str
536- WHERE str NOT LIKE '%Heap Blocks%';
537- result
531+ SELECT str FROM expln('
532+ EXPLAIN (ANALYZE, VERBOSE, COSTS OFF, SUMMARY OFF, TIMING OFF)
533+ SELECT count(*) FROM t WHERE x < 3 AND mod(x,3) = 1') AS str
534+ WHERE str NOT LIKE '%Heap Blocks%' AND str NOT LIKE '%Query Identifier%';
535+ str
538536-----------------------------------------------------------------
539537 Aggregate (actual rows=1 loops=1)
540538 AQO not used
@@ -590,6 +588,10 @@ ORDER BY (md5(query_text),error) DESC;
590588 | SELECT count(*) FROM t WHERE +
591589 | x = (SELECT avg(x) FROM t t0 WHERE t0.x = t.x + 21) OR +
592590 | x IN (SELECT avg(x) FROM t t0 WHERE t0.x = t.x + 21);
591+ 0.106 | +
592+ | EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +
593+ | SELECT * FROM t GROUP BY (x) HAVING x > 3; +
594+ |
593595 0.454 | SELECT count(*) FROM (SELECT x, y FROM t1 GROUP BY GROUPING SETS ((x,y), (x), (y), ())) AS q1;
594596 0.000 | SELECT count(*) FROM ( +
595597 | SELECT count(*) AS x FROM ( +
@@ -602,10 +604,6 @@ ORDER BY (md5(query_text),error) DESC;
602604 0.000 | EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +
603605 | SELECT count(*) FROM t WHERE (SELECT avg(x) FROM t t0 WHERE t0.x = t.x) = +
604606 | (SELECT avg(x) FROM t t0 WHERE t0.x = t.x);
605- 0.106 | +
606- | EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +
607- | SELECT * FROM t GROUP BY (x) HAVING x > 3; +
608- |
609607 0.000 | SELECT count(*) FROM +
610608 | (SELECT * FROM t WHERE x % 3 < (SELECT avg(x) FROM t t0 WHERE t0.x = t.x)) AS q1 +
611609 | JOIN +