The relevant clause here is probably the difference between the “size ratio” and the “total size of the relationship”:
CREATE TABLE test_table AS SELECT ('<a>' || repeat('x', 1000000) || '</a>')::xml AS "xml" FROM generate_series(1, 2560); SELECT pg_size_pretty(pg_relation_size('test_table')) AS relation_size, pg_size_pretty(pg_total_relation_size('test_table')) AS total_relation_size; relation_size | total_relation_size
Large column values like these are not stored in the main relation, but are instead transferred to the corresponding TOAST table. This external storage is not taken into account in relation to pg_relation_size() , which, according to the optimizer, is compared with min_parallel_relation_size when evaluating a parallel plan:
SET parallel_setup_cost = 0; SET parallel_tuple_cost = 0; SET min_parallel_relation_size = '144kB'; EXPLAIN SELECT xpath('/a', "xml") FROM test_table; QUERY PLAN
SET min_parallel_relation_size = '136kB'; EXPLAIN SELECT xpath('/a', "xml") FROM test_table; QUERY PLAN
source share