]> git.8kb.co.uk Git - postgresql/pg_update_chunks/blob - pg_chunk_update.sh
Fix formatting of README.md
[postgresql/pg_update_chunks] / pg_chunk_update.sh
1 #!/bin/bash
2
3 # Example script to split full table updates into chunks with a vacuum inbetween
4 # to try and avoid table bloat.
5 # Sometimes it's better to create a new table and swap them, but when that's not possible
6 # due to other complications something like this may do.
7
8 ## CREATE TABLE test(ax integer PRIMARY KEY, bx text);
9 ## INSERT INTO test SELECT i, 'SOME TEXT ' || i FROM generate_series(1,1000000) i;
10
11 psql_prefix="/usr/local/pgsql/bin"
12 user="pgcontrol"
13 database="SEE"
14 schema="public"
15 relation="test"
16 fields="bx"                             # Comma separated
17 values="'SOMETHING ELSE ' || ax"        # Comma separated
18 pk="ax"
19 skip_pk_vals="0"                        # Comma separated
20 chunks=50
21 sql="SELECT count(*)/$chunks FROM $schema.$relation WHERE $pk NOT IN ($skip_pk_vals) AND (($fields) IS NULL OR ($fields) <> ($values));"
22 chunk_size=`$psql_prefix/psql -U $user -d $database -tAc "$sql"`
23
24 echo "CHUNK SIZE $chunk_size"
25
26 for i in `seq 1 $(($chunks-1))`; do
27         echo "CHUNK $i)"
28         offset=$((($i-1)*$chunk_size))
29
30         sql="$(cat <<-EOF
31                 UPDATE $schema.$relation a
32                 SET ($fields) = ($values)
33                 FROM (SELECT ctid FROM $schema.$relation WHERE $pk NOT IN ($skip_pk_vals) AND (($fields) IS NULL OR ($fields) <> ($values)) ORDER BY ctid LIMIT $chunk_size) b
34                 WHERE a.ctid = b.ctid
35                 AND (($fields) IS NULL OR ($fields) <> ($values));
36 EOF
37         )"
38         echo $sql
39         result=`$psql_prefix/psql -U $user -d $database -c "$sql"`
40         echo $result
41
42         sql="VACUUM $schema.$relation;"
43         echo $sql
44         result=`$psql_prefix/psql -U $user -d $database -c "$sql"`
45         echo $result
46 done
47
48 sql="UPDATE $schema.$relation SET ($fields) = ($values) WHERE ($fields) <> ($values);"
49 echo $sql
50 result=`$psql_prefix/psql -U $user -d $database -c "$sql"`
51 echo $result
52
53 sql="VACUUM ANALYZE $schema.$relation;"
54 echo $sql
55 result=`$psql_prefix/psql -U $user -d $database -c "$sql"`
56 echo $result
57