On 6/13/21 2:40 AM, Alvaro Herrera wrote:
> On 2021-Jun-12, Tomas Vondra wrote:
>
>> There's one caveat, though - for regular builds the slowdown is pretty
>> much eliminated. But with valgrind it's still considerably slower. For
>> postgres_fdw the "make check" used to take ~5 minutes for me, now it
>> takes >1h. And yes, this is entirely due to the new test case which is
>> generating / inserting 70k rows. So maybe the test case is not worth it
>> after all, and we should get rid of it.
>
> Hmm, what if the table is made 1600 columns wide -- would inserting 41
> rows be sufficient to trigger the problem case? If it does, maybe it
> would reduce the runtime for valgrind/cache-clobber animals enough that
> it's no longer a concern.
>
Good idea. I gave that a try, creating a table with 1500 columns and
inserting 50 rows (so 75k parameters). See the attached patch.
While this cuts the runtime about in half (to ~30 minutes on my laptop),
that's probably not enough - it's still about ~6x longer than it used to
take. All these timings are with valgrind.
regards
--
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql
index 8cb2148f1f..0c6bc240b7 100644
--- a/contrib/postgres_fdw/sql/postgres_fdw.sql
+++ b/contrib/postgres_fdw/sql/postgres_fdw.sql
@@ -3026,13 +3026,6 @@ SELECT COUNT(*) FROM ftable;
TRUNCATE batch_table;
DROP FOREIGN TABLE ftable;
--- try if large batches exceed max number of bind parameters
-CREATE FOREIGN TABLE ftable ( x int ) SERVER loopback OPTIONS ( table_name 'batch_table', batch_size '100000' );
-INSERT INTO ftable SELECT * FROM generate_series(1, 70000) i;
-SELECT COUNT(*) FROM ftable;
-TRUNCATE batch_table;
-DROP FOREIGN TABLE ftable;
-
-- Disable batch insert
CREATE FOREIGN TABLE ftable ( x int ) SERVER loopback OPTIONS ( table_name 'batch_table', batch_size '1' );
EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable VALUES (1), (2);
@@ -3041,6 +3034,46 @@ SELECT COUNT(*) FROM ftable;
DROP FOREIGN TABLE ftable;
DROP TABLE batch_table;
+
+CREATE OR REPLACE FUNCTION create_batch_tables(p_cnt int) RETURNS void AS $$
+DECLARE
+ v_sql_local text := '';
+ v_sql_foreign text := '';
+ v_i int;
+BEGIN
+
+ v_sql_local := 'CREATE TABLE batch_table (';
+ v_sql_foreign := 'CREATE FOREIGN TABLE ftable (';
+
+ FOR v_i IN 1 .. p_cnt LOOP
+
+ IF v_i > 1 THEN
+ v_sql_local := v_sql_local || ', col_' || v_i || ' int';
+ v_sql_foreign := v_sql_foreign || ', col_' || v_i || ' int';
+ ELSE
+ v_sql_local := v_sql_local || 'col_' || v_i || ' int';
+ v_sql_foreign := v_sql_foreign || 'col_' || v_i || ' int';
+ END IF;
+
+ END LOOP;
+
+ v_sql_local := v_sql_local || ')';
+ v_sql_foreign := v_sql_foreign || ') SERVER loopback OPTIONS (table_name ''batch_table'', batch_size ''100000'' )';
+
+ EXECUTE v_sql_local;
+ EXECUTE v_sql_foreign;
+
+END;
+$$ LANGUAGE plpgsql;
+
+-- try if large batches exceed max number of bind parameters
+SELECT create_batch_tables(1500);
+INSERT INTO ftable SELECT * FROM generate_series(1, 50) i;
+SELECT COUNT(*) FROM ftable;
+DROP TABLE batch_table;
+DROP FOREIGN TABLE ftable;
+DROP FUNCTION create_batch_tables(int);
+
-- Use partitioning
CREATE TABLE batch_table ( x int ) PARTITION BY HASH (x);