0

I want to compact a postgresql 11 db and my idea is to convert lots of bigint to int data types if and only if there is a reasonable lag to the limit of int data type considering the data inside.

So, can you help me in finding a script to find all bigint that can be converted to int fields in postgresql ?

asked Mar 23, 2020 at 11:19
2
  • 1
    If you are doing that for performance reasons, I doubt you will actually be able to measure any difference. It might reduce the occupied space on disc, but that's unlikely either. Commented Mar 23, 2020 at 12:13
  • thank you, I am doing for both, even a small improvement is welcome Commented Mar 23, 2020 at 12:43

1 Answer 1

1

Following script should help to do the job:

create or replace procedure cbi ()
language plpgsql
as $$
--
declare 
s text;
max_value bigint;
c cursor for
 select 
 pg_namespace.nspname, 
 pg_class.relname, 
 pg_attribute.attname, 
 pg_type.typname 
 from pg_class
 join pg_namespace
 on pg_class.relnamespace = pg_namespace.oid
 and pg_namespace.nspname <> 'pg_catalog'
 join pg_attribute
 on pg_class.oid = pg_attribute.attrelid
 join pg_type
 on pg_attribute.atttypid = pg_type.oid
 and pg_type.typname='int8'
 where pg_class.relkind in ('r','v');
begin
 for r in c
 loop
 s := 'select max(' || r.attname || ') from ' || r.nspname || '.' || r.relname; 
 execute s into max_value;
 if max_value <= +2147483647 and max_value >= -2147483648 
 then
 raise notice '%.%.% max=% can be replaced with int.', r.nspname, r.relname, r.attname, max_value;
 else
 raise notice '%.%.% max=% CANNOT be replaced with int.', r.nspname, r.relname, r.attname, max_value;
 end if;
 end loop;
end;
--
$$;

Example:

postgres=# call cbi();
NOTICE: public.pg_stat_statements.queryid max=9148650842799727408 CANNOT be replaced with int.
NOTICE: public.pg_stat_statements.calls max=118 can be replaced with int.
NOTICE: public.pg_stat_statements.rows max=4060311 can be replaced with int.
NOTICE: public.pg_stat_statements.shared_blks_hit max=577699 can be replaced with int.
NOTICE: public.pg_stat_statements.shared_blks_read max=637 can be replaced with int.
NOTICE: public.pg_stat_statements.shared_blks_dirtied max=991 can be replaced with int.
NOTICE: public.pg_stat_statements.shared_blks_written max=991 can be replaced with int.
NOTICE: public.pg_stat_statements.local_blks_hit max=0 can be replaced with int.
NOTICE: public.pg_stat_statements.local_blks_read max=0 can be replaced with int.
NOTICE: public.pg_stat_statements.local_blks_dirtied max=0 can be replaced with int.
NOTICE: public.pg_stat_statements.local_blks_written max=0 can be replaced with int.
NOTICE: public.pg_stat_statements.temp_blks_read max=171 can be replaced with int.
NOTICE: public.pg_stat_statements.temp_blks_written max=171 can be replaced with int.
NOTICE: public.t.x max=1 can be replaced with int.
CALL
postgres=# 
answered Mar 23, 2020 at 13:42
3
  • it gives me that error:: Errore SQL [42809]: ERROR: "antivirus_exception_pk" is an index¶ Dove: PL/pgSQL function cbi() line 25 at EXECUTE Commented Mar 23, 2020 at 14:02
  • 1
    I have fixed the script with where pg_class.relkind in ('r','v'); Commented Mar 23, 2020 at 14:12
  • tks a lot mister Commented Mar 23, 2020 at 14:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.