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);
 

Reply via email to