我有一个非常大的postgres数据库,其中有一个特定的模式,它被放入并在每晚重新创建.在创建该模式中的所有表之后,我想对它们进行真空分析,但是数据库是如此之大,以至于如果执行完整数据库VACUUM ANALYZE;则需要大约半小时.
如何在不为每个表编写单独的SQL命令的情况下,对此模式中的每个表进行真空分析?
下面的bash函数使用psql来真空分析由变量标识的模式中的表 psql
完全披露:我在最终发布问题之前制定了这个答案,但认为它可能对其他人有用,并且很想看到任何其他解决方案.
vacuum_analyze_schema() {
# vacuum analyze only the tables in the specified schema
# postgres info can be supplied by either passing it as parameters to this
# function, setting environment variables or a combination of the two
local pg_schema="${1:-${PG_SCHEMA}}"
local pg_db="${2:-${PG_DB}}"
local pg_user="${3:-${PG_USER}}"
local pg_host="${4:-${PG_HOST}}"
echo "Vacuuming schema \`${pg_schema}\`:"
# extract schema table names from psql output and put them in a bash array
local psql_tbls="\dt ${pg_schema}.*"
local sed_str="s/${pg_schema}\s+\|\s+(\w+)\s+\|.*/\1/p"
local table_names=$( echo "${psql_tbls}" | psql -d "${pg_db}" -U "${pg_user}" -h "${pg_host}" | sed -nr "${sed_str}" )
local tables_array=( $( echo "${table_names}" | tr '\n' ' ' ) )
# loop through the table names creating and executing a vacuum
# command for each one
for t in "${tables_array[@]}"; do
echo "doing table \`${t}\`..."
psql -d "${pg_db}" -U "${pg_user}" -h "${pg_host}" \
-c "VACUUM (ANALYZE) ${pg_schema}.${t};"
done
}
Run Code Online (Sandbox Code Playgroud)
小智 6
一个基于@Grant Humphries 和@Fritz 的解决方案,但更短更简单:
PGUSER=your_postgres_username
PGHOST=your_postgres_host
PGPORT=your_postgres_port
PGDB=your_postgres_db_name
PGSCHEMA=your_postgres_schema
for table in $(psql -h ${PGHOST} -p ${PGPORT} -d ${PGDB} -U ${PGUSER} \
-c "select tablename from pg_tables where schemaname = '${PGSCHEMA}';" | \
tail -n +3 | head -n -2); do
psql -h ${PGHOST} -p ${PGPORT} -d ${PGDB} -U ${PGUSER} \
-c "VACUUM (ANALYZE) ${PGSCHEMA}.${table};";
done
Run Code Online (Sandbox Code Playgroud)
与上述解决方案的差异:
您可以使用以下pl / pgsql脚本(如果您仅想分析,则无法从函数或多命令字符串执行真空):
DO $$
DECLARE
tab RECORD;
schemaName VARCHAR := 'your_schema';
BEGIN
for tab in (select t.relname::varchar AS table_name
FROM pg_class t
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE t.relkind = 'r' and n.nspname::varchar = schemaName
order by 1)
LOOP
RAISE NOTICE 'ANALYZE %1.%2', schemaName, tab.table_name;
EXECUTE 'ANALYZE '||schemaName||'.'||tab.table_name;
end loop;
end
$$;
Run Code Online (Sandbox Code Playgroud)
小智 5
这样做不是更简单:
psql -t -A -U postgres -c "select format('analyse verbose %I.%I;', n.nspname::varchar, t.relname::varchar) FROM pg_class t JOIN pg_namespace n ON n.oid = t.relnamespace WHERE t.relkind = 'r' and n.nspname::varchar = 'your_schema' order by 1" | psql -U postgres
Run Code Online (Sandbox Code Playgroud)
选项 -t 仅打印行(无标题)和 -A 避免格式化
| 归档时间: |
|
| 查看次数: |
19657 次 |
| 最近记录: |