From 242066cc8e587ccbe5e1cf38c4f085f080dcd5e0 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 7 Feb 2017 16:34:11 -0500 Subject: [PATCH] Speed up "brin" regression test a little bit. In the large DO block, collect row TIDs into array variables instead of creating and dropping a pile of temporary tables. In a normal build, this reduces the brin test script's runtime from about 1.1 sec to 0.4 sec on my workstation. That's not all that exciting perhaps, but in a CLOBBER_CACHE_ALWAYS test build, the runtime drops from 20 min to 17 min, which is a little more useful. In combination with some other changes I plan to propose, this will help provide a noticeable reduction in cycle time for CLOBBER_CACHE_ALWAYS buildfarm critters. --- src/test/regress/expected/brin.out | 42 +++++++++++------------------- src/test/regress/sql/brin.sql | 42 +++++++++++------------------- 2 files changed, 30 insertions(+), 54 deletions(-) diff --git a/src/test/regress/expected/brin.out b/src/test/regress/expected/brin.out index 21676e53a0..f0008dd31b 100644 --- a/src/test/regress/expected/brin.out +++ b/src/test/regress/expected/brin.out @@ -288,13 +288,13 @@ DECLARE r record; r2 record; cond text; + idx_ctids tid[]; + ss_ctids tid[]; count int; - mismatch bool; plan_ok bool; plan_line text; BEGIN FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers, unnest(op) WITH ORDINALITY AS oper LOOP - mismatch := false; -- prepare the condition IF r.value IS NULL THEN @@ -304,13 +304,12 @@ BEGIN END IF; -- run the query using the brin index - CREATE TEMP TABLE brin_result (cid tid); SET enable_seqscan = 0; SET enable_bitmapscan = 1; plan_ok := false; - FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT ctid FROM brintest WHERE %s $y$, cond) LOOP - IF plan_line LIKE 'Bitmap Heap Scan on brintest%' THEN + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Bitmap Heap Scan on brintest%' THEN plan_ok := true; END IF; END LOOP; @@ -318,16 +317,16 @@ BEGIN RAISE WARNING 'did not get bitmap indexscan plan for %', r; END IF; - EXECUTE format($y$INSERT INTO brin_result SELECT ctid FROM brintest WHERE %s $y$, cond); + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) + INTO idx_ctids; -- run the query using a seqscan - CREATE TEMP TABLE brin_result_ss (cid tid); SET enable_seqscan = 1; SET enable_bitmapscan = 0; plan_ok := false; - FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT ctid FROM brintest WHERE %s $y$, cond) LOOP - IF plan_line LIKE 'Seq Scan on brintest%' THEN + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Seq Scan on brintest%' THEN plan_ok := true; END IF; END LOOP; @@ -335,22 +334,16 @@ BEGIN RAISE WARNING 'did not get seqscan plan for %', r; END IF; - EXECUTE format($y$INSERT INTO brin_result_ss SELECT ctid FROM brintest WHERE %s $y$, cond); + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) + INTO ss_ctids; -- make sure both return the same results - PERFORM * FROM brin_result EXCEPT ALL SELECT * FROM brin_result_ss; - GET DIAGNOSTICS count = ROW_COUNT; - IF count <> 0 THEN - mismatch = true; - END IF; - PERFORM * FROM brin_result_ss EXCEPT ALL SELECT * FROM brin_result; - GET DIAGNOSTICS count = ROW_COUNT; - IF count <> 0 THEN - mismatch = true; - END IF; + count := array_length(idx_ctids, 1); - -- report the results of each scan to make the differences obvious - IF mismatch THEN + IF NOT (count = array_length(ss_ctids, 1) AND + idx_ctids @> ss_ctids AND + idx_ctids <@ ss_ctids) THEN + -- report the results of each scan to make the differences obvious RAISE WARNING 'something not right in %: count %', r, count; SET enable_seqscan = 1; SET enable_bitmapscan = 0; @@ -366,12 +359,7 @@ BEGIN END IF; -- make sure we found expected number of matches - SELECT count(*) INTO count FROM brin_result; IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF; - - -- drop the temporary tables - DROP TABLE brin_result; - DROP TABLE brin_result_ss; END LOOP; END; $x$; diff --git a/src/test/regress/sql/brin.sql b/src/test/regress/sql/brin.sql index e7f6f77901..5bf53873f7 100644 --- a/src/test/regress/sql/brin.sql +++ b/src/test/regress/sql/brin.sql @@ -294,13 +294,13 @@ DECLARE r record; r2 record; cond text; + idx_ctids tid[]; + ss_ctids tid[]; count int; - mismatch bool; plan_ok bool; plan_line text; BEGIN FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers, unnest(op) WITH ORDINALITY AS oper LOOP - mismatch := false; -- prepare the condition IF r.value IS NULL THEN @@ -310,13 +310,12 @@ BEGIN END IF; -- run the query using the brin index - CREATE TEMP TABLE brin_result (cid tid); SET enable_seqscan = 0; SET enable_bitmapscan = 1; plan_ok := false; - FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT ctid FROM brintest WHERE %s $y$, cond) LOOP - IF plan_line LIKE 'Bitmap Heap Scan on brintest%' THEN + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Bitmap Heap Scan on brintest%' THEN plan_ok := true; END IF; END LOOP; @@ -324,16 +323,16 @@ BEGIN RAISE WARNING 'did not get bitmap indexscan plan for %', r; END IF; - EXECUTE format($y$INSERT INTO brin_result SELECT ctid FROM brintest WHERE %s $y$, cond); + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) + INTO idx_ctids; -- run the query using a seqscan - CREATE TEMP TABLE brin_result_ss (cid tid); SET enable_seqscan = 1; SET enable_bitmapscan = 0; plan_ok := false; - FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT ctid FROM brintest WHERE %s $y$, cond) LOOP - IF plan_line LIKE 'Seq Scan on brintest%' THEN + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Seq Scan on brintest%' THEN plan_ok := true; END IF; END LOOP; @@ -341,22 +340,16 @@ BEGIN RAISE WARNING 'did not get seqscan plan for %', r; END IF; - EXECUTE format($y$INSERT INTO brin_result_ss SELECT ctid FROM brintest WHERE %s $y$, cond); + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) + INTO ss_ctids; -- make sure both return the same results - PERFORM * FROM brin_result EXCEPT ALL SELECT * FROM brin_result_ss; - GET DIAGNOSTICS count = ROW_COUNT; - IF count <> 0 THEN - mismatch = true; - END IF; - PERFORM * FROM brin_result_ss EXCEPT ALL SELECT * FROM brin_result; - GET DIAGNOSTICS count = ROW_COUNT; - IF count <> 0 THEN - mismatch = true; - END IF; + count := array_length(idx_ctids, 1); - -- report the results of each scan to make the differences obvious - IF mismatch THEN + IF NOT (count = array_length(ss_ctids, 1) AND + idx_ctids @> ss_ctids AND + idx_ctids <@ ss_ctids) THEN + -- report the results of each scan to make the differences obvious RAISE WARNING 'something not right in %: count %', r, count; SET enable_seqscan = 1; SET enable_bitmapscan = 0; @@ -372,12 +365,7 @@ BEGIN END IF; -- make sure we found expected number of matches - SELECT count(*) INTO count FROM brin_result; IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF; - - -- drop the temporary tables - DROP TABLE brin_result; - DROP TABLE brin_result_ss; END LOOP; END; $x$; -- 2.40.0