rails-pg-extras 0.5.2 → 0.6.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc8fd2765b1470aa6c7f8786b0f2cbe89ae543dfe02339091d5d4d3af8decb82
4
- data.tar.gz: c0d29ac67ae447bb91e75bd48a87a7d148cc6da05ab9430dd5b138be5d598a0f
3
+ metadata.gz: 20731f025eef43ea51d93e24a0af36bf8b1cf693343cd37ab6d44d6ae59b1939
4
+ data.tar.gz: f9d6b9b16ad4c67bc12129308923282d2d58cba133f586fbad91b8fb55769723
5
5
  SHA512:
6
- metadata.gz: 1a958d2044dd13b23daf446f7e776fc735800e5a7b7efcf90f52ec178c203c6442e920e3c97c41c82d34940835fa6de006e7de5be62838cad1842457adc60510
7
- data.tar.gz: b9f9d733cd3d292fe5282785458d46a40a051a76feb5504bd59f7d138844f091997635258c76cf08e561ffae47be80b3e68669db177a5be75c94f77583b53ac2
6
+ metadata.gz: 89b82f1052f8e1147efbfab860890324d2402356e9c2c84dbafaed5ef1945521d49a2e46f4fc080c7c50b812dd4d887e76ce01e8a07c8c86411af33b69685120
7
+ data.tar.gz: 504af4370b1e1a82f7ddd0bb048619e0d22d36928a332ade78e1e6c3509100cd155c331512917af123ca7c375805d658f97a507b1070ba8ac30249add48d21f2
data/.gitignore CHANGED
@@ -3,4 +3,5 @@ Gemfile.lock
3
3
  pkg/
4
4
  *.gem
5
5
  docker-compose.yml
6
+ .byebug_history
6
7
 
data/README.md CHANGED
@@ -366,7 +366,7 @@ This command outputs the Mandelbrot set, calculated through SQL.
366
366
 
367
367
  * Does is not violate the Heroku PG Extras license?
368
368
 
369
- The original plugin is [MIT based](https://github.com/heroku/heroku-pg-extras/blob/master/LICENSE) so it means that copying and redistribution in any format is permitted.
369
+ The original plugin is MIT based so it means that copying and redistribution in any format is permitted.
370
370
 
371
371
  ## Disclaimer
372
372
 
@@ -1,17 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'terminal-table'
4
+ require 'ruby-pg-extras'
4
5
 
5
6
  module RailsPGExtras
6
- QUERIES = %i(
7
- bloat blocking cache_hit
8
- calls extensions
9
- index_size index_usage locks all_locks
10
- long_running_queries mandelbrot outliers
11
- records_rank seq_scans table_indexes_size
12
- table_size total_index_size total_table_size
13
- unused_indexes vacuum_stats
14
- )
7
+ QUERIES = RubyPGExtras::QUERIES
15
8
 
16
9
  QUERIES.each do |query_name|
17
10
  define_singleton_method query_name do |options = { in_format: :display_table }|
@@ -24,71 +17,21 @@ module RailsPGExtras
24
17
 
25
18
  def self.run_query(query_name:, in_format:)
26
19
  result = connection.execute(
27
- sql_for(query_name: query_name)
20
+ RubyPGExtras.sql_for(query_name: query_name)
28
21
  )
29
22
 
30
- display_result(
23
+ RubyPGExtras.display_result(
31
24
  result,
32
- title: description_for(query_name: query_name),
25
+ title: RubyPGExtras.description_for(query_name: query_name),
33
26
  in_format: in_format
34
27
  )
35
28
  end
36
29
 
37
- def self.display_result(result, title:, in_format:)
38
- case in_format
39
- when :array
40
- result.values
41
- when :hash
42
- result.to_a
43
- when :raw
44
- result
45
- when :display_table
46
- headings = if result.count > 0
47
- result[0].keys
48
- else
49
- ["No results"]
50
- end
51
-
52
- puts Terminal::Table.new(
53
- title: title,
54
- headings: headings,
55
- rows: result.values
56
- )
57
- else
58
- raise "Invalid in_format option"
59
- end
60
- end
61
-
62
- def self.description_for(query_name:)
63
- first_line = File.open(
64
- sql_path_for(query_name: query_name)
65
- ) { |f| f.readline }
66
-
67
- first_line[/\/\*(.*?)\*\//m, 1].strip
68
- end
69
-
70
- def self.sql_for(query_name:)
71
- File.read(
72
- sql_path_for(query_name: query_name)
73
- )
74
- end
75
-
76
- def self.sql_path_for(query_name:)
77
- File.join(File.dirname(__FILE__), "/rails-pg-extras/queries/#{query_name}.sql")
78
- end
79
-
80
30
  def self.connection
81
31
  ActiveRecord::Base.connection
82
32
  end
83
33
 
84
- %i(
85
- connection
86
- display_result
87
- sql_for
88
- sql_path_for
89
- ).each do |method_name|
90
- private_class_method method_name
91
- end
34
+ private_class_method :connection
92
35
  end
93
36
 
94
37
  require 'rails-pg-extras/railtie' if defined?(Rails)
@@ -4,7 +4,7 @@ require 'rails-pg-extras'
4
4
 
5
5
  namespace :pg_extras do
6
6
  RailsPGExtras::QUERIES.each do |query_name|
7
- desc RailsPGExtras.description_for(query_name: query_name)
7
+ desc RubyPGExtras.description_for(query_name: query_name)
8
8
  task query_name.to_sym => :environment do
9
9
  RailsPGExtras.public_send(query_name)
10
10
  end
@@ -1,3 +1,3 @@
1
1
  module RailsPGExtras
2
- VERSION = "0.5.2"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -18,6 +18,7 @@ Gem::Specification.new do |gem|
18
18
  gem.add_dependency "activerecord"
19
19
  gem.add_dependency "pg"
20
20
  gem.add_dependency "terminal-table"
21
+ gem.add_dependency "ruby-pg-extras", RailsPGExtras::VERSION
21
22
  gem.add_development_dependency "rake"
22
23
  gem.add_development_dependency "rspec"
23
24
  end
data/spec/smoke_spec.rb CHANGED
@@ -3,22 +3,12 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe RailsPGExtras do
6
- RailsPGExtras::QUERIES.each do |query_name|
7
- it "#{query_name} description can be read" do
8
- expect do
9
- RailsPGExtras.description_for(
10
- query_name: query_name
11
- )
12
- end.not_to raise_error
13
- end
14
- end
15
-
16
6
  PG_STATS_DEPENDENT_QUERIES = %i(calls outliers)
17
7
 
18
8
  (RailsPGExtras::QUERIES - PG_STATS_DEPENDENT_QUERIES).each do |query_name|
19
9
  it "#{query_name} query can be executed" do
20
10
  expect do
21
- result = RailsPGExtras.run_query(
11
+ RailsPGExtras.run_query(
22
12
  query_name: query_name,
23
13
  in_format: :hash
24
14
  )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-pg-extras
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-02 00:00:00.000000000 Z
11
+ date: 2020-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: ruby-pg-extras
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.6.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 0.6.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -96,26 +110,6 @@ files:
96
110
  - README.md
97
111
  - Rakefile
98
112
  - lib/rails-pg-extras.rb
99
- - lib/rails-pg-extras/queries/all_locks.sql
100
- - lib/rails-pg-extras/queries/bloat.sql
101
- - lib/rails-pg-extras/queries/blocking.sql
102
- - lib/rails-pg-extras/queries/cache_hit.sql
103
- - lib/rails-pg-extras/queries/calls.sql
104
- - lib/rails-pg-extras/queries/extensions.sql
105
- - lib/rails-pg-extras/queries/index_size.sql
106
- - lib/rails-pg-extras/queries/index_usage.sql
107
- - lib/rails-pg-extras/queries/locks.sql
108
- - lib/rails-pg-extras/queries/long_running_queries.sql
109
- - lib/rails-pg-extras/queries/mandelbrot.sql
110
- - lib/rails-pg-extras/queries/outliers.sql
111
- - lib/rails-pg-extras/queries/records_rank.sql
112
- - lib/rails-pg-extras/queries/seq_scans.sql
113
- - lib/rails-pg-extras/queries/table_indexes_size.sql
114
- - lib/rails-pg-extras/queries/table_size.sql
115
- - lib/rails-pg-extras/queries/total_index_size.sql
116
- - lib/rails-pg-extras/queries/total_table_size.sql
117
- - lib/rails-pg-extras/queries/unused_indexes.sql
118
- - lib/rails-pg-extras/queries/vacuum_stats.sql
119
113
  - lib/rails-pg-extras/railtie.rb
120
114
  - lib/rails-pg-extras/tasks/all.rake
121
115
  - lib/rails-pg-extras/version.rb
@@ -1,16 +0,0 @@
1
- /* Queries with active locks */
2
-
3
- SELECT
4
- pg_stat_activity.pid,
5
- pg_class.relname,
6
- pg_locks.transactionid,
7
- pg_locks.granted,
8
- pg_locks.mode,
9
- pg_stat_activity.query AS query_snippet,
10
- age(now(),pg_stat_activity.query_start) AS "age"
11
- FROM pg_stat_activity,pg_locks left
12
- OUTER JOIN pg_class
13
- ON (pg_locks.relation = pg_class.oid)
14
- WHERE pg_stat_activity.query <> '<insufficient privilege>'
15
- AND pg_locks.pid = pg_stat_activity.pid
16
- AND pg_stat_activity.pid <> pg_backend_pid() order by query_start;
@@ -1,63 +0,0 @@
1
- /* Table and index bloat in your database ordered by most wasteful */
2
-
3
- WITH constants AS (
4
- SELECT current_setting('block_size')::numeric AS bs, 23 AS hdr, 4 AS ma
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 (
11
- SELECT
12
- schemaname, tablename, hdr, ma, bs,
13
- SUM((1-null_frac)*avg_width) AS datawidth,
14
- MAX(null_frac) AS maxfracsum,
15
- hdr+(
16
- SELECT 1+count(*)/8
17
- FROM pg_stats s2
18
- WHERE null_frac<>0 AND s2.schemaname = s.schemaname AND s2.tablename = s.tablename
19
- ) AS nullhdr
20
- FROM pg_stats s, constants
21
- GROUP BY 1,2,3,4,5
22
- ) AS foo
23
- ), table_bloat AS (
24
- SELECT
25
- schemaname, tablename, cc.relpages, bs,
26
- CEIL((cc.reltuples*((datahdr+ma-
27
- (CASE WHEN datahdr%ma=0 THEN ma ELSE datahdr%ma END))+nullhdr2+4))/(bs-20::float)) AS otta
28
- FROM bloat_info
29
- JOIN pg_class cc ON cc.relname = bloat_info.tablename
30
- JOIN pg_namespace nn ON cc.relnamespace = nn.oid AND nn.nspname = bloat_info.schemaname AND nn.nspname <> 'information_schema'
31
- ), index_bloat AS (
32
- SELECT
33
- schemaname, tablename, bs,
34
- COALESCE(c2.relname,'?') AS iname, COALESCE(c2.reltuples,0) AS ituples, COALESCE(c2.relpages,0) AS ipages,
35
- COALESCE(CEIL((c2.reltuples*(datahdr-12))/(bs-20::float)),0) AS iotta -- very rough approximation, assumes all cols
36
- FROM bloat_info
37
- JOIN pg_class cc ON cc.relname = bloat_info.tablename
38
- JOIN pg_namespace nn ON cc.relnamespace = nn.oid AND nn.nspname = bloat_info.schemaname AND nn.nspname <> 'information_schema'
39
- JOIN pg_index i ON indrelid = cc.oid
40
- JOIN pg_class c2 ON c2.oid = i.indexrelid
41
- )
42
- SELECT
43
- type, schemaname, object_name, bloat, pg_size_pretty(raw_waste) as waste
44
- FROM
45
- (SELECT
46
- 'table' as type,
47
- schemaname,
48
- tablename as object_name,
49
- ROUND(CASE WHEN otta=0 THEN 0.0 ELSE table_bloat.relpages/otta::numeric END,1) AS bloat,
50
- CASE WHEN relpages < otta THEN '0' ELSE (bs*(table_bloat.relpages-otta)::bigint)::bigint END AS raw_waste
51
- FROM
52
- table_bloat
53
- UNION
54
- SELECT
55
- 'index' as type,
56
- schemaname,
57
- tablename || '::' || iname as object_name,
58
- ROUND(CASE WHEN iotta=0 OR ipages=0 THEN 0.0 ELSE ipages/iotta::numeric END,1) AS bloat,
59
- CASE WHEN ipages < iotta THEN '0' ELSE (bs*(ipages-iotta))::bigint END AS raw_waste
60
- FROM
61
- index_bloat) bloat_summary
62
- ORDER BY raw_waste DESC, bloat DESC;
63
-
@@ -1,16 +0,0 @@
1
- /* Queries holding locks other queries are waiting to be released */
2
-
3
- SELECT bl.pid AS blocked_pid,
4
- ka.query AS blocking_statement,
5
- now() - ka.query_start AS blocking_duration,
6
- kl.pid AS blocking_pid,
7
- a.query AS blocked_statement,
8
- now() - a.query_start AS blocked_duration
9
- FROM pg_catalog.pg_locks bl
10
- JOIN pg_catalog.pg_stat_activity a
11
- ON bl.pid = a.pid
12
- JOIN pg_catalog.pg_locks kl
13
- JOIN pg_catalog.pg_stat_activity ka
14
- ON kl.pid = ka.pid
15
- ON bl.transactionid = kl.transactionid AND bl.pid != kl.pid
16
- WHERE NOT bl.granted;
@@ -1,11 +0,0 @@
1
- /* Index and table hit rate */
2
-
3
- SELECT
4
- 'index hit rate' AS name,
5
- (sum(idx_blks_hit)) / nullif(sum(idx_blks_hit + idx_blks_read),0) AS ratio
6
- FROM pg_statio_user_indexes
7
- UNION ALL
8
- SELECT
9
- 'table hit rate' AS name,
10
- sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read),0) AS ratio
11
- FROM pg_statio_user_tables;
@@ -1,9 +0,0 @@
1
- /* 10 queries that have longest execution time in aggregate */
2
-
3
- SELECT query AS qry,
4
- interval '1 millisecond' * total_time AS exec_time,
5
- to_char((total_time/sum(total_time) OVER()) * 100, 'FM90D0') || '%' AS prop_exec_time,
6
- to_char(calls, 'FM999G999G990') AS ncalls,
7
- interval '1 millisecond' * (blk_read_time + blk_write_time) AS sync_io_time
8
- FROM pg_stat_statements WHERE userid = (SELECT usesysid FROM pg_user WHERE usename = current_user LIMIT 1)
9
- ORDER BY calls DESC LIMIT 10;
@@ -1,4 +0,0 @@
1
- /* Available and installed extensions */
2
-
3
- SELECT * FROM pg_available_extensions ORDER BY installed_version;
4
-
@@ -1,11 +0,0 @@
1
- /* The size of indexes, descending by size */
2
-
3
- SELECT c.relname AS name,
4
- pg_size_pretty(sum(c.relpages::bigint*8192)::bigint) AS size
5
- FROM pg_class c
6
- LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
7
- WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
8
- AND n.nspname !~ '^pg_toast'
9
- AND c.relkind='i'
10
- GROUP BY c.relname
11
- ORDER BY sum(c.relpages) DESC;
@@ -1,12 +0,0 @@
1
- /* Index hit rate (effective databases are at 99% and up) */
2
-
3
- SELECT relname,
4
- CASE idx_scan
5
- WHEN 0 THEN 'Insufficient data'
6
- ELSE (100 * idx_scan / (seq_scan + idx_scan))::text
7
- END percent_of_times_index_used,
8
- n_live_tup rows_in_table
9
- FROM
10
- pg_stat_user_tables
11
- ORDER BY
12
- n_live_tup DESC;
@@ -1,16 +0,0 @@
1
- /* Queries with active exclusive locks */
2
-
3
- SELECT
4
- pg_stat_activity.pid,
5
- pg_class.relname,
6
- pg_locks.transactionid,
7
- pg_locks.granted,
8
- pg_stat_activity.query AS query_snippet,
9
- age(now(),pg_stat_activity.query_start) AS "age"
10
- FROM pg_stat_activity,pg_locks left
11
- OUTER JOIN pg_class
12
- ON (pg_locks.relation = pg_class.oid)
13
- WHERE pg_stat_activity.query <> '<insufficient privilege>'
14
- AND pg_locks.pid = pg_stat_activity.pid
15
- AND pg_locks.mode = 'ExclusiveLock'
16
- AND pg_stat_activity.pid <> pg_backend_pid() order by query_start;
@@ -1,14 +0,0 @@
1
- /* All queries longer than five minutes by descending duration */
2
-
3
- SELECT
4
- pid,
5
- now() - pg_stat_activity.query_start AS duration,
6
- query AS query
7
- FROM
8
- pg_stat_activity
9
- WHERE
10
- pg_stat_activity.query <> ''::text
11
- AND state <> 'idle'
12
- AND now() - pg_stat_activity.query_start > interval '5 minutes'
13
- ORDER BY
14
- now() - pg_stat_activity.query_start DESC;
@@ -1,21 +0,0 @@
1
- /* The mandelbrot set */
2
-
3
- WITH RECURSIVE Z(IX, IY, CX, CY, X, Y, I) AS (
4
- SELECT IX, IY, X::float, Y::float, X::float, Y::float, 0
5
- FROM (select -2.2 + 0.031 * i, i from generate_series(0,101) as i) as xgen(x,ix),
6
- (select -1.5 + 0.031 * i, i from generate_series(0,101) as i) as ygen(y,iy)
7
- UNION ALL
8
- SELECT IX, IY, CX, CY, X * X - Y * Y + CX AS X, Y * X * 2 + CY, I + 1
9
- FROM Z
10
- WHERE X * X + Y * Y < 16::float
11
- AND I < 100
12
- )
13
- SELECT array_to_string(array_agg(SUBSTRING(' .,,,-----++++%%%%@@@@#### ', LEAST(GREATEST(I,1),27), 1)),'')
14
- FROM (
15
- SELECT IX, IY, MAX(I) AS I
16
- FROM Z
17
- GROUP BY IY, IX
18
- ORDER BY IY, IX
19
- ) AS ZT
20
- GROUP BY IY
21
- ORDER BY IY;
@@ -1,10 +0,0 @@
1
- /* 10 queries that have longest execution time in aggregate */
2
-
3
- SELECT interval '1 millisecond' * total_time AS total_exec_time,
4
- to_char((total_time/sum(total_time) OVER()) * 100, 'FM90D0') || '%' AS prop_exec_time,
5
- to_char(calls, 'FM999G999G999G990') AS ncalls,
6
- interval '1 millisecond' * (blk_read_time + blk_write_time) AS sync_io_time,
7
- query AS query
8
- FROM pg_stat_statements WHERE userid = (SELECT usesysid FROM pg_user WHERE usename = current_user LIMIT 1)
9
- ORDER BY total_time DESC
10
- LIMIT 10;
@@ -1,9 +0,0 @@
1
- /* All tables and the number of rows in each ordered by number of rows descending */
2
-
3
- SELECT
4
- relname AS name,
5
- n_live_tup AS estimated_count
6
- FROM
7
- pg_stat_user_tables
8
- ORDER BY
9
- n_live_tup DESC;
@@ -1,7 +0,0 @@
1
- /* Count of sequential scans by table descending by order */
2
-
3
- SELECT relname AS name,
4
- seq_scan as count
5
- FROM
6
- pg_stat_user_tables
7
- ORDER BY seq_scan DESC;
@@ -1,10 +0,0 @@
1
- /* Total size of all the indexes on each table, descending by size */
2
-
3
- SELECT c.relname AS table,
4
- pg_size_pretty(pg_indexes_size(c.oid)) AS index_size
5
- FROM pg_class c
6
- LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
7
- WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
8
- AND n.nspname !~ '^pg_toast'
9
- AND c.relkind='r'
10
- ORDER BY pg_indexes_size(c.oid) DESC;
@@ -1,10 +0,0 @@
1
- /* Size of the tables (excluding indexes), descending by size */
2
-
3
- SELECT c.relname AS name,
4
- pg_size_pretty(pg_table_size(c.oid)) AS size
5
- FROM pg_class c
6
- LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
7
- WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
8
- AND n.nspname !~ '^pg_toast'
9
- AND c.relkind='r'
10
- ORDER BY pg_table_size(c.oid) DESC;
@@ -1,8 +0,0 @@
1
- /* Total size of all indexes in MB */
2
-
3
- SELECT pg_size_pretty(sum(c.relpages::bigint*8192)::bigint) AS size
4
- FROM pg_class c
5
- LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
6
- WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
7
- AND n.nspname !~ '^pg_toast'
8
- AND c.relkind='i';
@@ -1,10 +0,0 @@
1
- /* Size of the tables (including indexes), descending by size */
2
-
3
- SELECT c.relname AS name,
4
- pg_size_pretty(pg_total_relation_size(c.oid)) AS size
5
- FROM pg_class c
6
- LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
7
- WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
8
- AND n.nspname !~ '^pg_toast'
9
- AND c.relkind='r'
10
- ORDER BY pg_total_relation_size(c.oid) DESC;
@@ -1,16 +0,0 @@
1
- /* Unused and almost unused indexes */
2
- /* Ordered by their size relative to the number of index scans.
3
- Exclude indexes of very small tables (less than 5 pages),
4
- where the planner will almost invariably select a sequential scan,
5
- but may not in the future as the table grows */
6
-
7
- SELECT
8
- schemaname || '.' || relname AS table,
9
- indexrelname AS index,
10
- pg_size_pretty(pg_relation_size(i.indexrelid)) AS index_size,
11
- idx_scan as index_scans
12
- FROM pg_stat_user_indexes ui
13
- JOIN pg_index i ON ui.indexrelid = i.indexrelid
14
- WHERE NOT indisunique AND idx_scan < 50 AND pg_relation_size(relid) > 5 * 8192
15
- ORDER BY pg_relation_size(i.indexrelid) / nullif(idx_scan, 0) DESC NULLS FIRST,
16
- pg_relation_size(i.indexrelid) DESC;
@@ -1,40 +0,0 @@
1
- /* Dead rows and whether an automatic vacuum is expected to be triggered */
2
-
3
- WITH table_opts AS (
4
- SELECT
5
- pg_class.oid, relname, nspname, array_to_string(reloptions, '') AS relopts
6
- FROM
7
- pg_class INNER JOIN pg_namespace ns ON relnamespace = ns.oid
8
- ), vacuum_settings AS (
9
- SELECT
10
- oid, relname, nspname,
11
- CASE
12
- WHEN relopts LIKE '%autovacuum_vacuum_threshold%'
13
- THEN substring(relopts, '.*autovacuum_vacuum_threshold=([0-9.]+).*')::integer
14
- ELSE current_setting('autovacuum_vacuum_threshold')::integer
15
- END AS autovacuum_vacuum_threshold,
16
- CASE
17
- WHEN relopts LIKE '%autovacuum_vacuum_scale_factor%'
18
- THEN substring(relopts, '.*autovacuum_vacuum_scale_factor=([0-9.]+).*')::real
19
- ELSE current_setting('autovacuum_vacuum_scale_factor')::real
20
- END AS autovacuum_vacuum_scale_factor
21
- FROM
22
- table_opts
23
- )
24
- SELECT
25
- vacuum_settings.nspname AS schema,
26
- vacuum_settings.relname AS table,
27
- to_char(psut.last_vacuum, 'YYYY-MM-DD HH24:MI') AS last_vacuum,
28
- to_char(psut.last_autovacuum, 'YYYY-MM-DD HH24:MI') AS last_autovacuum,
29
- to_char(pg_class.reltuples, '9G999G999G999') AS rowcount,
30
- to_char(psut.n_dead_tup, '9G999G999G999') AS dead_rowcount,
31
- to_char(autovacuum_vacuum_threshold
32
- + (autovacuum_vacuum_scale_factor::numeric * pg_class.reltuples), '9G999G999G999') AS autovacuum_threshold,
33
- CASE
34
- WHEN autovacuum_vacuum_threshold + (autovacuum_vacuum_scale_factor::numeric * pg_class.reltuples) < psut.n_dead_tup
35
- THEN 'yes'
36
- END AS expect_autovacuum
37
- FROM
38
- pg_stat_user_tables psut INNER JOIN pg_class ON psut.relid = pg_class.oid
39
- INNER JOIN vacuum_settings ON pg_class.oid = vacuum_settings.oid
40
- ORDER BY 1;