Friday, August 01. 2008How to determine which tables are missing indexesPrinter FriendlyRecommended Books: PostGIS In Action PostgreSQL 8.4 Official The SQL Language PostgreSQL 8.4 Server Administration
Trackbacks
Trackback specific URI for this entry
No Trackbacks
Comments
Display comments as
(Linear | Threaded)
More valuable may be the ability to see which tables are doing full table scans vs index scans. After all, lack of index scans not only tell you there is either no index but rather there may be a bad one. try this.
CREATE OR REPLACE VIEW pg_table_nonindex_x AS SELECT x1.table_in_trouble, pg_relation_size(x1.table_in_trouble) AS sz_n_byts, x1.seq_scan, x1.idx_scan, CASE WHEN pg_relation_size(x1.table_in_trouble) > 500000000 THEN 'Exceeds 500 megs, too large to count in a view. For a count, count individually'::text ELSE x_count(x1.table_in_trouble)::text END AS tbl_rec_count, x1.priority FROM ( SELECT (pg_stat_all_tables.schemaname::text || '.'::text) || pg_stat_all_tables.relname::text AS table_in_trouble, pg_stat_all_tables.seq_scan, pg_stat_all_tables.idx_scan, CASE WHEN (pg_stat_all_tables.seq_scan - pg_stat_all_tables.idx_scan) < 500 THEN 'Minor Problem'::text WHEN (pg_stat_all_tables.seq_scan - pg_stat_all_tables.idx_scan) >= 500 AND (pg_stat_all_tables.seq_scan - pg_stat_all_tables.idx_scan) < 2500 THEN 'Major Problem'::text WHEN (pg_stat_all_tables.seq_scan - pg_stat_all_tables.idx_scan) >= 2500 THEN 'Extreme Problem'::text ELSE NULL::text END AS priority FROM pg_stat_all_tables WHERE pg_stat_all_tables.seq_scan > pg_stat_all_tables.idx_scan AND pg_stat_all_tables.schemaname 'pg_catalog'::name AND pg_stat_all_tables.seq_scan > 100) x1 ORDER BY x1.priority DESC, x1.seq_scan;
I had a few issues with the view, so I changed it below. Hope this helps as well!
CREATE OR REPLACE VIEW pg_table_nonindex_x AS SELECT x1.table_in_trouble, pg_relation_size(x1.table_in_trouble) AS sz_n_byts, x1.seq_scan, x1.idx_scan, CASE WHEN pg_relation_size(x1.table_in_trouble) > 500000000 THEN 'Exceeds 500 megs, too large to count in a view. For a count, count individually'::text ELSE count(x1.table_in_trouble)::text END AS tbl_rec_count, x1.priority FROM ( SELECT (schemaname::text || '.'::text) || relname::text AS table_in_trouble, seq_scan, idx_scan, CASE WHEN (seq_scan - idx_scan) < 500 THEN 'Minor Problem'::text WHEN (seq_scan - idx_scan) >= 500 AND (seq_scan - idx_scan) < 2500 THEN 'Major Problem'::text WHEN (seq_scan - idx_scan) >= 2500 THEN 'Extreme Problem'::text ELSE NULL::text END AS priority FROM pg_stat_all_tables WHERE seq_scan > idx_scan AND schemaname != 'pg_catalog'::name AND seq_scan > 100) x1 GROUP BY x1.table_in_trouble, x1.seq_scan, x1.idx_scan, x1.priority ORDER BY x1.priority DESC, x1.seq_scan ; SELECT * FROM pg_table_nonindex_x;
Is there anything in Postgres 8.3/8.4 to help identify only outdated/bloated indexex to be rebuilt?
I found the query below in Postgres Documentation posted by Tom Lane as a reply to:“pg_stat_user_indexes view clarification” and is supposed to list all indexes candidates for REINDEX: select schemaname,relname,indexrelname,idx_tup_read,idx_tup_fetch from pg_stat_user_indexes where idx_tup_read != idx_tup_fetch; Is this still valid in Postgres 8.3/8.4? I also found another statement somewhere on the net and can this be also something to rely on or not? Currently I’m running maintenance tasks (vacuum,analyze,reindex,analyze) on all databases all indexes but due to their number and size this takes many hours to complete. I’m sure that by not reindexing all tables.indexes I can save lots of maintenance time but not sure how to identify only outdated/bloated PG indexes easily. --100 is general rule but I took 10 to be more aggressive on the reindex. select schemaname,relname,indexrelname,idx_scan,idx_tup_read,idx_tup_fetch from pg_stat_all_user_indexes where idx_tup_fetch > (idx_scan * 10) and idx_scan 0 and schemaname = 'public' Any hint greatly appreciated. |
Entry's LinksQuicksearchCalendar
Categories
Blog Administration |