0

Not a complete database noob, but I've done a ton of research on this and I still can't figure this out. I've got a PostgreSQL database tied to a CMS. It currently has 470 columns in one of the table (long story), and I'm trying to figure out how close we are to maxing things out.

If I run

SELECT SUM(pg_column_size(table_name.*))/COUNT(*) FROM tablename;

I get back

enter image description here

If I run

SELECT l.metric, l.nr AS bytes
     , CASE WHEN is_size THEN pg_size_pretty(nr) END AS bytes_pretty
     , CASE WHEN is_size THEN nr / NULLIF(x.ct, 0) END AS bytes_per_row
FROM  (
   SELECT min(tableoid)        AS tbl      -- = 'public.tbl'::regclass::oid
        , count(*)             AS ct
        , sum(length(t::text)) AS txt_len  -- length in characters
   FROM   table_name t                     -- provide table name *once*
   ) x
CROSS  JOIN LATERAL (
   VALUES
     (true , 'core_relation_size'               , pg_relation_size(tbl))
   , (true , 'visibility_map'                   , pg_relation_size(tbl, 'vm'))
   , (true , 'free_space_map'                   , pg_relation_size(tbl, 'fsm'))
   , (true , 'table_size_incl_toast'            , pg_table_size(tbl))
   , (true , 'indexes_size'                     , pg_indexes_size(tbl))
   , (true , 'total_size_incl_toast_and_indexes', pg_total_relation_size(tbl))
   , (true , 'live_rows_in_text_representation' , txt_len)
   , (false, '------------------------------'   , NULL)
   , (false, 'row_count'                        , ct)
   , (false, 'live_tuples'                      , pg_stat_get_live_tuples(tbl))
   , (false, 'dead_tuples'                      , pg_stat_get_dead_tuples(tbl))
   ) l(is_size, metric, nr);

Then I get back enter image description here

Can anyone help make sense of this, or give me some other things to check?

2
  • Can you please clarify what exactly does not make sense to you? Which "things" do you think are close to "maxing out"?
    – mustaccio
    Commented May 6, 2023 at 0:06
  • That's what I'm trying to figure out. I see the limitations in the PostgreSQL documentation about columns per row (1600) but then it depends on the tuple size fitting on a single page. Just trying to figure out where we currently sit - or if that's even possible?
    – Todd
    Commented May 6, 2023 at 0:23

1 Answer 1

0

It depends on the data types of the columns and the actual values being stored. If every column is of a toastable type, in my hands a table of 470 columns will start to throw errors if more than 448 of those columns are not null and large. This is relatively easy to demonstrate with the \gexec feature of psql.

select 'create table wide ('||string_agg('col'||x::text||' text',',')||')' from generate_series(1,470) f(x) \gexec

select 'insert into wide values ('||string_agg('md5(random()::text)',',')||')' from generate_series(1,449) f(x) \gexec

yielding:

ERROR:  row is too big: size 8176, maximum size 8160
3
  • The majority of the fields are checkboxes and dropdown menus.
    – Todd
    Commented May 6, 2023 at 23:32
  • @Todd That describes the GUI used to populate them. It doesn't tell us anything about the columns themselves. Although I guess it means they are shortish, so you probably won't have a problem
    – jjanes
    Commented May 8, 2023 at 16:26
  • Yeah, I wasn't sure if that would matter.
    – Todd
    Commented May 8, 2023 at 23:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.