pg-stats 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/queries/bloat.sql +117 -58
- data/queries/blocking-queries.sql +16 -9
- data/queries/cache-hit-rate.sql +5 -4
- data/queries/extensions.sql +7 -1
- data/queries/index-size.sql +15 -8
- data/queries/index-usage.sql +7 -6
- data/queries/locks.sql +10 -6
- data/queries/long-running-queries.sql +3 -3
- data/queries/outliers.sql +23 -8
- data/queries/seq-scans.sql +5 -3
- data/queries/slow-statements.sql +23 -7
- data/queries/table-indexes-size.sql +13 -7
- data/queries/table-size.sql +12 -7
- data/queries/total-index-size.sql +11 -6
- data/queries/total-table-size.sql +12 -7
- data/queries/unused-indexes.sql +12 -5
- data/queries/vacuum.sql +6 -2
- data/scripts/cache-hit-rate.sh +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e621fc8e0c48634775ea2900f893961830848e582a027713de9fb50dbc109da
|
4
|
+
data.tar.gz: 9c10943edee1b52e1ea39e51be577e51c8114e41495b3ad09024426f0500134c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8586306450c8f4efdc01bd19bdd9ca4d057310e4f20928c7da66e35c721e656e9284ee5b958b902d94d2fff05cc6c866ddb2756b57bc42d806a592579fc9885d
|
7
|
+
data.tar.gz: 9675a5a7d7332a7a43d06ac35d8f1f347b5e22362609c995203a89a404ada143b449bb2e7e346de82f4346c377645badacff6896f6d7c2230a3f05e0aeaf5238
|
data/queries/bloat.sql
CHANGED
@@ -1,63 +1,122 @@
|
|
1
1
|
/* Table and index bloat in your database ordered by most wasteful */
|
2
2
|
|
3
|
-
WITH
|
4
|
-
|
5
|
-
), bloat_info AS (
|
6
|
-
SELECT
|
7
|
-
ma,bs,schemaname,tablename,
|
8
|
-
(datawidth+(hdr+ma-(case when hdr%ma=0 THEN ma ELSE hdr%ma END)))::numeric AS datahdr,
|
9
|
-
(maxfracsum*(nullhdr+ma-(case when nullhdr%ma=0 THEN ma ELSE nullhdr%ma END))) AS nullhdr2
|
10
|
-
FROM (
|
3
|
+
WITH
|
4
|
+
constants AS (
|
11
5
|
SELECT
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
)
|
6
|
+
current_setting('block_size')::numeric AS bs,
|
7
|
+
23 AS hdr,
|
8
|
+
4 AS ma
|
9
|
+
),
|
10
|
+
bloat_info AS (
|
11
|
+
SELECT
|
12
|
+
ma,
|
13
|
+
bs,
|
14
|
+
schemaname,
|
15
|
+
tablename,
|
16
|
+
(datawidth+(hdr+ma-(case when hdr%ma=0 THEN ma ELSE hdr%ma END)))::numeric AS datahdr,
|
17
|
+
(maxfracsum*(nullhdr+ma-(case when nullhdr%ma=0 THEN ma ELSE nullhdr%ma END))) AS nullhdr2
|
18
|
+
FROM (
|
19
|
+
SELECT
|
20
|
+
schemaname,
|
21
|
+
tablename,
|
22
|
+
hdr,
|
23
|
+
ma,
|
24
|
+
bs,
|
25
|
+
SUM((1-null_frac)*avg_width) AS datawidth,
|
26
|
+
MAX(null_frac) AS maxfracsum,
|
27
|
+
hdr+(
|
28
|
+
SELECT
|
29
|
+
1+count(*)/8
|
30
|
+
FROM
|
31
|
+
pg_stats s2
|
32
|
+
WHERE
|
33
|
+
null_frac<>0 AND
|
34
|
+
s2.schemaname = s.schemaname AND
|
35
|
+
s2.tablename = s.tablename
|
36
|
+
) AS nullhdr
|
37
|
+
FROM
|
38
|
+
pg_stats s,
|
39
|
+
constants
|
40
|
+
GROUP BY
|
41
|
+
1,
|
42
|
+
2,
|
43
|
+
3,
|
44
|
+
4,
|
45
|
+
5
|
46
|
+
) AS foo
|
47
|
+
),
|
48
|
+
table_bloat AS (
|
49
|
+
SELECT
|
50
|
+
schemaname,
|
51
|
+
tablename,
|
52
|
+
cc.relpages,
|
53
|
+
bs,
|
54
|
+
CEIL((cc.reltuples*((datahdr+ma-
|
55
|
+
(CASE WHEN datahdr%ma=0 THEN ma ELSE datahdr%ma END))+nullhdr2+4))/(bs-20::float)) AS otta
|
56
|
+
FROM
|
57
|
+
bloat_info
|
58
|
+
JOIN
|
59
|
+
pg_class cc ON
|
60
|
+
cc.relname = bloat_info.tablename
|
61
|
+
JOIN
|
62
|
+
pg_namespace nn ON
|
63
|
+
cc.relnamespace = nn.oid AND
|
64
|
+
nn.nspname = bloat_info.schemaname AND
|
65
|
+
nn.nspname <> 'information_schema'
|
66
|
+
),
|
67
|
+
index_bloat AS (
|
68
|
+
SELECT
|
69
|
+
schemaname,
|
70
|
+
tablename,
|
71
|
+
bs,
|
72
|
+
COALESCE(c2.relname,'?') AS iname,
|
73
|
+
COALESCE(c2.reltuples,0) AS ituples,
|
74
|
+
COALESCE(c2.relpages,0) AS ipages,
|
75
|
+
COALESCE(CEIL((c2.reltuples*(datahdr-12))/(bs-20::float)),0) AS iotta -- very rough approximation, assumes all cols
|
76
|
+
FROM
|
77
|
+
bloat_info
|
78
|
+
JOIN
|
79
|
+
pg_class cc
|
80
|
+
ON cc.relname = bloat_info.tablename
|
81
|
+
JOIN
|
82
|
+
pg_namespace nn ON
|
83
|
+
cc.relnamespace = nn.oid AND
|
84
|
+
nn.nspname = bloat_info.schemaname AND
|
85
|
+
nn.nspname <> 'information_schema'
|
86
|
+
JOIN
|
87
|
+
pg_index i ON
|
88
|
+
indrelid = cc.oid
|
89
|
+
JOIN
|
90
|
+
pg_class c2 ON
|
91
|
+
c2.oid = i.indexrelid
|
92
|
+
)
|
93
|
+
|
32
94
|
SELECT
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
(
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
FROM
|
61
|
-
index_bloat) bloat_summary
|
62
|
-
ORDER BY raw_waste DESC, bloat DESC;
|
95
|
+
type,
|
96
|
+
schemaname,
|
97
|
+
object_name,
|
98
|
+
bloat,
|
99
|
+
pg_size_pretty(raw_waste) as waste
|
100
|
+
FROM
|
101
|
+
(
|
102
|
+
SELECT
|
103
|
+
'table' as type,
|
104
|
+
schemaname,
|
105
|
+
tablename as object_name,
|
106
|
+
ROUND(CASE WHEN otta=0 THEN 0.0 ELSE table_bloat.relpages/otta::numeric END,1) AS bloat,
|
107
|
+
CASE WHEN relpages < otta THEN '0' ELSE (bs*(table_bloat.relpages-otta)::bigint)::bigint END AS raw_waste
|
108
|
+
FROM
|
109
|
+
table_bloat
|
110
|
+
UNION SELECT
|
111
|
+
'index' as type,
|
112
|
+
schemaname,
|
113
|
+
tablename || '::' || iname as object_name,
|
114
|
+
ROUND(CASE WHEN iotta=0 OR ipages=0 THEN 0.0 ELSE ipages/iotta::numeric END,1) AS bloat,
|
115
|
+
CASE WHEN ipages < iotta THEN '0' ELSE (bs*(ipages-iotta))::bigint END AS raw_waste
|
116
|
+
FROM
|
117
|
+
index_bloat
|
118
|
+
) bloat_summary
|
119
|
+
ORDER BY
|
120
|
+
raw_waste DESC,
|
121
|
+
bloat DESC;
|
63
122
|
|
@@ -1,16 +1,23 @@
|
|
1
1
|
/* Queries holding locks which other queries are waiting to be released */
|
2
2
|
|
3
|
-
SELECT
|
3
|
+
SELECT
|
4
|
+
bl.pid AS blocked_pid,
|
4
5
|
ka.query AS blocking_statement,
|
5
6
|
now() - ka.query_start AS blocking_duration,
|
6
7
|
kl.pid AS blocking_pid,
|
7
8
|
a.query AS blocked_statement,
|
8
9
|
now() - a.query_start AS blocked_duration
|
9
|
-
FROM
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
FROM
|
11
|
+
pg_catalog.pg_locks bl
|
12
|
+
JOIN
|
13
|
+
pg_catalog.pg_stat_activity a ON
|
14
|
+
bl.pid = a.pid
|
15
|
+
JOIN
|
16
|
+
pg_catalog.pg_locks kl
|
17
|
+
JOIN
|
18
|
+
pg_catalog.pg_stat_activity ka ON
|
19
|
+
kl.pid = ka.pid ON
|
20
|
+
bl.transactionid = kl.transactionid AND
|
21
|
+
bl.pid != kl.pid
|
22
|
+
WHERE
|
23
|
+
NOT bl.granted;
|
data/queries/cache-hit-rate.sql
CHANGED
@@ -3,9 +3,10 @@
|
|
3
3
|
SELECT
|
4
4
|
'index hit rate' AS name,
|
5
5
|
(sum(idx_blks_hit)) / nullif(sum(idx_blks_hit + idx_blks_read),0) AS ratio
|
6
|
-
FROM
|
7
|
-
|
8
|
-
SELECT
|
6
|
+
FROM
|
7
|
+
pg_statio_user_indexes
|
8
|
+
UNION ALL SELECT
|
9
9
|
'table hit rate' AS name,
|
10
10
|
sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read),0) AS ratio
|
11
|
-
FROM
|
11
|
+
FROM
|
12
|
+
pg_statio_user_tables;
|
data/queries/extensions.sql
CHANGED
data/queries/index-size.sql
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
/* The size of indexes, descending by size */
|
2
2
|
|
3
|
-
SELECT
|
3
|
+
SELECT
|
4
|
+
c.relname AS name,
|
4
5
|
pg_size_pretty(sum(c.relpages::bigint*8192)::bigint) AS size
|
5
|
-
FROM
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
FROM
|
7
|
+
pg_class c
|
8
|
+
LEFT JOIN
|
9
|
+
pg_namespace n ON
|
10
|
+
(n.oid = c.relnamespace)
|
11
|
+
WHERE
|
12
|
+
n.nspname NOT IN ('pg_catalog', 'information_schema') AND
|
13
|
+
n.nspname !~ '^pg_toast' AND
|
14
|
+
c.relkind='i'
|
15
|
+
GROUP BY
|
16
|
+
c.relname
|
17
|
+
ORDER BY
|
18
|
+
sum(c.relpages) DESC;
|
data/queries/index-usage.sql
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
/* Index hit rate (effective databases are at 99% and up) */
|
2
2
|
|
3
|
-
SELECT
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
SELECT
|
4
|
+
relname,
|
5
|
+
CASE idx_scan
|
6
|
+
WHEN 0 THEN 'Insufficient data'
|
7
|
+
ELSE (100 * idx_scan / (seq_scan + idx_scan))::text
|
8
|
+
END percent_of_times_index_used,
|
9
|
+
n_live_tup rows_in_table
|
9
10
|
FROM
|
10
11
|
pg_stat_user_tables
|
11
12
|
ORDER BY
|
data/queries/locks.sql
CHANGED
@@ -8,9 +8,13 @@ SELECT
|
|
8
8
|
pg_locks.mode,
|
9
9
|
pg_stat_activity.query AS query_snippet,
|
10
10
|
age(now(),pg_stat_activity.query_start) AS "age"
|
11
|
-
FROM
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
FROM
|
12
|
+
pg_stat_activity,
|
13
|
+
pg_locks
|
14
|
+
LEFT OUTER JOIN
|
15
|
+
pg_class ON
|
16
|
+
(pg_locks.relation = pg_class.oid)
|
17
|
+
WHERE
|
18
|
+
pg_stat_activity.query <> '<insufficient privilege>' AND
|
19
|
+
pg_locks.pid = pg_stat_activity.pid AND
|
20
|
+
pg_stat_activity.pid <> pg_backend_pid() order by query_start;
|
@@ -7,8 +7,8 @@ SELECT
|
|
7
7
|
FROM
|
8
8
|
pg_stat_activity
|
9
9
|
WHERE
|
10
|
-
pg_stat_activity.query <> ''::text
|
11
|
-
|
12
|
-
|
10
|
+
pg_stat_activity.query <> ''::text AND
|
11
|
+
state <> 'idle' AND
|
12
|
+
now() - pg_stat_activity.query_start > interval '1 minute'
|
13
13
|
ORDER BY
|
14
14
|
now() - pg_stat_activity.query_start DESC;
|
data/queries/outliers.sql
CHANGED
@@ -1,10 +1,25 @@
|
|
1
1
|
/* 10 queries that have longest execution time in aggregate */
|
2
2
|
|
3
|
-
SELECT
|
4
|
-
|
5
|
-
to_char(
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
SELECT
|
4
|
+
interval '1 millisecond' * total_time AS total_exec_time,
|
5
|
+
to_char((total_time/sum(total_time) OVER()) * 100, 'FM90D0') || '%' AS prop_exec_time,
|
6
|
+
to_char(calls, 'FM999G999G999G990') AS ncalls,
|
7
|
+
interval '1 millisecond' * (blk_read_time + blk_write_time) AS sync_io_time,
|
8
|
+
query AS query
|
9
|
+
FROM
|
10
|
+
pg_stat_statements
|
11
|
+
WHERE
|
12
|
+
userid = (
|
13
|
+
SELECT
|
14
|
+
usesysid
|
15
|
+
FROM
|
16
|
+
pg_user
|
17
|
+
WHERE
|
18
|
+
usename = current_user
|
19
|
+
LIMIT
|
20
|
+
1
|
21
|
+
)
|
22
|
+
ORDER BY
|
23
|
+
total_time DESC
|
24
|
+
LIMIT
|
25
|
+
10;
|
data/queries/seq-scans.sql
CHANGED
data/queries/slow-statements.sql
CHANGED
@@ -1,9 +1,25 @@
|
|
1
1
|
/* 10 queries that have longest execution time in aggregate */
|
2
2
|
|
3
|
-
SELECT
|
4
|
-
|
5
|
-
|
6
|
-
to_char(
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
SELECT
|
4
|
+
query AS qry,
|
5
|
+
interval '1 millisecond' * total_time AS exec_time,
|
6
|
+
to_char((total_time/sum(total_time) OVER()) * 100, 'FM90D0') || '%' AS prop_exec_time,
|
7
|
+
to_char(calls, 'FM999G999G990') AS ncalls,
|
8
|
+
interval '1 millisecond' * (blk_read_time + blk_write_time) AS sync_io_time
|
9
|
+
FROM
|
10
|
+
pg_stat_statements
|
11
|
+
WHERE
|
12
|
+
userid = (
|
13
|
+
SELECT
|
14
|
+
usesysid
|
15
|
+
FROM
|
16
|
+
pg_user
|
17
|
+
WHERE
|
18
|
+
usename = current_user
|
19
|
+
LIMIT
|
20
|
+
1
|
21
|
+
)
|
22
|
+
ORDER BY
|
23
|
+
calls DESC
|
24
|
+
LIMIT
|
25
|
+
10;
|
@@ -1,10 +1,16 @@
|
|
1
1
|
/* Total size of all the indexes on each table, descending by size */
|
2
2
|
|
3
|
-
SELECT
|
3
|
+
SELECT
|
4
|
+
c.relname AS table,
|
4
5
|
pg_size_pretty(pg_indexes_size(c.oid)) AS index_size
|
5
|
-
FROM
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
FROM
|
7
|
+
pg_class c
|
8
|
+
LEFT JOIN
|
9
|
+
pg_namespace n ON
|
10
|
+
(n.oid = c.relnamespace)
|
11
|
+
WHERE
|
12
|
+
n.nspname NOT IN ('pg_catalog', 'information_schema') AND
|
13
|
+
n.nspname !~ '^pg_toast' AND
|
14
|
+
c.relkind='r'
|
15
|
+
ORDER BY
|
16
|
+
pg_indexes_size(c.oid) DESC;
|
data/queries/table-size.sql
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
/* Size of the tables (excluding indexes), descending by size */
|
2
2
|
|
3
|
-
SELECT
|
3
|
+
SELECT
|
4
|
+
c.relname AS name,
|
4
5
|
pg_size_pretty(pg_table_size(c.oid)) AS size
|
5
|
-
FROM
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
FROM
|
7
|
+
pg_class c
|
8
|
+
LEFT JOIN
|
9
|
+
pg_namespace n ON
|
10
|
+
(n.oid = c.relnamespace)
|
11
|
+
WHERE
|
12
|
+
n.nspname NOT IN ('pg_catalog', 'information_schema') AND
|
13
|
+
n.nspname !~ '^pg_toast' AND c.relkind='r'
|
14
|
+
ORDER BY
|
15
|
+
pg_table_size(c.oid) DESC;
|
@@ -1,8 +1,13 @@
|
|
1
1
|
/* Total size of all indexes in MB */
|
2
2
|
|
3
|
-
SELECT
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
SELECT
|
4
|
+
pg_size_pretty(sum(c.relpages::bigint*8192)::bigint) AS size
|
5
|
+
FROM
|
6
|
+
pg_class c
|
7
|
+
LEFT JOIN
|
8
|
+
pg_namespace n ON
|
9
|
+
(n.oid = c.relnamespace)
|
10
|
+
WHERE
|
11
|
+
n.nspname NOT IN ('pg_catalog', 'information_schema') AND
|
12
|
+
n.nspname !~ '^pg_toast' AND
|
13
|
+
c.relkind='i';
|
@@ -1,10 +1,15 @@
|
|
1
1
|
/* Size of the tables (including indexes), descending by size */
|
2
2
|
|
3
|
-
SELECT
|
3
|
+
SELECT
|
4
|
+
c.relname AS name,
|
4
5
|
pg_size_pretty(pg_total_relation_size(c.oid)) AS size
|
5
|
-
FROM
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
FROM
|
7
|
+
pg_class c
|
8
|
+
LEFT JOIN
|
9
|
+
pg_namespace n ON
|
10
|
+
(n.oid = c.relnamespace)
|
11
|
+
WHERE
|
12
|
+
n.nspname NOT IN ('pg_catalog', 'information_schema') AND
|
13
|
+
n.nspname !~ '^pg_toast' AND c.relkind='r'
|
14
|
+
ORDER BY
|
15
|
+
pg_total_relation_size(c.oid) DESC;
|
data/queries/unused-indexes.sql
CHANGED
@@ -9,8 +9,15 @@ SELECT
|
|
9
9
|
indexrelname AS index,
|
10
10
|
pg_size_pretty(pg_relation_size(i.indexrelid)) AS index_size,
|
11
11
|
idx_scan as index_scans
|
12
|
-
FROM
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
FROM
|
13
|
+
pg_stat_user_indexes ui
|
14
|
+
JOIN
|
15
|
+
pg_index i ON
|
16
|
+
ui.indexrelid = i.indexrelid
|
17
|
+
WHERE
|
18
|
+
NOT indisunique AND
|
19
|
+
idx_scan < 50 AND
|
20
|
+
pg_relation_size(relid) > 5 * 8192
|
21
|
+
ORDER BY
|
22
|
+
pg_relation_size(i.indexrelid) / nullif(idx_scan, 0) DESC NULLS FIRST,
|
23
|
+
pg_relation_size(i.indexrelid) DESC;
|
data/queries/vacuum.sql
CHANGED
@@ -35,6 +35,10 @@ SELECT
|
|
35
35
|
THEN 'yes'
|
36
36
|
END AS expect_autovacuum
|
37
37
|
FROM
|
38
|
-
pg_stat_user_tables psut INNER JOIN
|
39
|
-
|
38
|
+
pg_stat_user_tables psut INNER JOIN
|
39
|
+
pg_class ON
|
40
|
+
psut.relid = pg_class.oid
|
41
|
+
INNER JOIN
|
42
|
+
vacuum_settings ON
|
43
|
+
pg_class.oid = vacuum_settings.oid
|
40
44
|
ORDER BY 1;
|
data/scripts/cache-hit-rate.sh
CHANGED