Perhaps there's a more idiomatic approach to this in Postgres, but the pattern is reasonably common so I expected it to work.
Here's the code:
drop table if exists tbl;
create temporary table tbl as select time, NULL as time_ts
from generate_series(1,20000000) as g(time);
drop table if exists timing;
create table timing(
info text,
n_rows integer,
iteration integer,
time timestamptz);
select now() as before;
DO
$body$
DECLARE
_value_array integer[] := '{
100,
20000,
5000000
}
';
t INTEGER;
iterator integer := 0;
table_name text := 'test_table';
BEGIN
FOREACH t IN ARRAY _value_array
LOOP
-- add to time table
insert into timing(info, n_rows, iteration, time)
values (format('(%I) before', table_name), t, iterator, now());
-- Run update
EXECUTE format(
'with cte as( '
'select time '
'from tbl '
'where time_ts '
'is null '
'limit %s '
') '
'update tbl '
'set time_ts = cte.time '
'from cte '
'where tbl.time = cte.time;', t);
-- add to time table
insert into timing(info, n_rows, iteration, time)
values (format('(%I) after', table_name), t, iterator, now());
iterator := iterator + 1;
END LOOP;
END
$body$;
select now() as after;
For which I get the output:
before
───────────────────────────────
2023-01-17 01:14:17.056198+00
(1 row)
after
───────────────────────────────
2023-01-17 01:14:44.871277+00
(1 row)
And the timing
table has the content:
info │ n_rows │ iteration │ time
─────────────────────┼─────────┼───────────┼───────────────────────────────
(test_table) before │ 100 │ 0 │ 2023-01-17 01:14:27.756752+00
(test_table) after │ 100 │ 0 │ 2023-01-17 01:14:27.756752+00
(test_table) before │ 20000 │ 1 │ 2023-01-17 01:14:27.756752+00
(test_table) after │ 20000 │ 1 │ 2023-01-17 01:14:27.756752+00
(test_table) before │ 5000000 │ 2 │ 2023-01-17 01:14:27.756752+00
(test_table) after │ 5000000 │ 2 │ 2023-01-17 01:14:27.756752+00
(6 rows)
The time within the timing table is at least somewhere between before
and after
, but I don't understand why they're all exactly the same time.
The output that I'm expecting to see is for each row to have a different time in it, as I would like to know how long each iteration took.