-- The update and delete triggers of the track_changes indexes of one table look up the same keys in the same unique index and find the same dead addresses: a statement probes the -- unique index once for all of them, not once for each index. Each index still gets its own tombstones (the answer is the log of each, equal to the one an only index writes). CREATE EXTENSION pg_sift; CREATE EXTENSION pg_sift_test; SET client_min_messages = warning; SET max_parallel_workers_per_gather = 0; CREATE TABLE t (id int PRIMARY KEY, g int NOT NULL, v int, w int) WITH (autovacuum_enabled = false, fillfactor = 100); INSERT INTO t SELECT i, i % 10, i, 0 FROM generate_series(1, 3000) i; CREATE INDEX t_a ON t USING sift_col (id, g, v); CREATE INDEX t_b ON t USING sift_col (id, g, w); CREATE INDEX t_c ON t USING sift_col (id, v); -- the scans of the primary key one statement made (statistics of the transaction), and the tombstones of the statement in the log of an index CREATE FUNCTION pk_scans() RETURNS int LANGUAGE sql AS $$ SELECT coalesce(pg_stat_get_xact_numscans('t_pkey'::regclass), 0)::int $$; CREATE FUNCTION log_tombs(idx regclass) RETURNS int LANGUAGE sql AS $$ SELECT count(*)::int FROM sift._test_col_log_entries(idx) WHERE kind = 1 AND txid_status(xid::text::bigint) IS DISTINCT FROM 'aborted' $$; -- three indexes BEGIN; SELECT pk_scans() AS before \gset DELETE FROM t WHERE id BETWEEN 1 AND 600; SELECT pk_scans() - :before AS d3_scans, log_tombs('t_a') AS d3_tombs \gset SELECT log_tombs('t_a') = log_tombs('t_b') AND log_tombs('t_b') = log_tombs('t_c') AS same_log; SELECT pk_scans() AS before \gset UPDATE t SET id = id + 100000 WHERE id BETWEEN 601 AND 900; SELECT pk_scans() - :before AS k3_scans, log_tombs('t_a') AS k3_tombs \gset SELECT log_tombs('t_a') = log_tombs('t_b') AND log_tombs('t_b') = log_tombs('t_c') AS same_log; ROLLBACK; -- one index DROP INDEX t_b; DROP INDEX t_c; BEGIN; SELECT pk_scans() AS before \gset DELETE FROM t WHERE id BETWEEN 1 AND 600; SELECT pk_scans() - :before AS d1_scans, log_tombs('t_a') AS d1_tombs \gset SELECT pk_scans() AS before \gset UPDATE t SET id = id + 100000 WHERE id BETWEEN 601 AND 900; SELECT pk_scans() - :before AS k1_scans, log_tombs('t_a') AS k1_tombs \gset ROLLBACK; -- the probe is shared: the scans of the key do not grow with the indexes, and the log of each is what an only index writes SELECT :d3_scans = :d1_scans AS delete_probe_shared, :d1_scans > 0 AS delete_probes, :d3_tombs = :d1_tombs AS delete_same_log, :k3_tombs = :k1_tombs AS key_same_log; DROP FUNCTION pk_scans(); DROP FUNCTION log_tombs(regclass); DROP TABLE t; DROP EXTENSION pg_sift_test; DROP EXTENSION pg_sift;