ruby-pg-extras 1.4.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 943bbbbd7e2de25570164a5bbd5e6015708ca2f808e7f0b25523a4125ad1bbf0
4
- data.tar.gz: dd4e28f9900f2b50eae39232828c47ebb7c6b57dbb9ca4042be074cda1214e75
3
+ metadata.gz: 517f1d39dfe5d78d1e8f7650767664b9bc349bf062efb60b421e568afe65be82
4
+ data.tar.gz: b60152d78952c4dc8bcee791d445d1aa0028d60bb0af47736095c5b587f605bd
5
5
  SHA512:
6
- metadata.gz: 12dd59913848f989fe6c186fefcdeb6418ab41cd6082b65f072b48d7d961e5d43b5c41822f8527bfda64e4557d284d52e74c0c3bd6dc1ca722fc958fa77d6b2a
7
- data.tar.gz: 6c2d5445c0acb5eb93f614f778464c1059807112ca310efac9f135ca025985783ee553b7dca99e269d932a7d447c736011b54e791897e7e8671832492ee87add
6
+ metadata.gz: 8d827609746ab9a203a80c40945ca4b394d9014443d3fb89ae938734d996e3dc3e7f9bce584a7d98297a490365b76e8209e3d43501f932c9c7d39078891f77d4
7
+ data.tar.gz: 95dd7b3bb562e194ddac894b9f1e66d05d37d933561333a127ae9dca649c0e2b2259a46b518117b06bcce72729574250b46be935e3f2245eaf9c812ed48346ad
data/README.md CHANGED
@@ -109,6 +109,8 @@ RubyPGExtras.cache_hit
109
109
 
110
110
  This command provides information on the efficiency of the buffer cache, for both index reads (`index hit rate`) as well as table reads (`table hit rate`). A low buffer cache hit ratio can be a sign that the Postgres instance is too small for the workload.
111
111
 
112
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#cache-hit)
113
+
112
114
  ### `index_cache_hit`
113
115
 
114
116
  ```ruby
@@ -125,6 +127,8 @@ RubyPGExtras.index_cache_hit
125
127
 
126
128
  The same as `cache_hit` with each table's indexes cache hit info displayed separately.
127
129
 
130
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#cache-hit)
131
+
128
132
  ### `table_cache_hit`
129
133
 
130
134
  ```ruby
@@ -141,6 +145,28 @@ RubyPGExtras.table_cache_hit
141
145
 
142
146
  The same as `cache_hit` with each table's cache hit info displayed seperately.
143
147
 
148
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#cache-hit)
149
+
150
+ ### `db_settings`
151
+
152
+ ```ruby
153
+
154
+ RubyPGExtras.db_settings
155
+
156
+ name | setting | unit |
157
+ ------------------------------+---------+------+
158
+ checkpoint_completion_target | 0.7 | |
159
+ default_statistics_target | 100 | |
160
+ effective_cache_size | 1350000 | 8kB |
161
+ effective_io_concurrency | 1 | |
162
+ (truncated results for brevity)
163
+
164
+ ```
165
+
166
+ This method displays values for selected PostgreSQL settings. You can compare them with settings recommended by [PGTune](https://pgtune.leopard.in.ua/#/) and tweak values to improve performance.
167
+
168
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#cache-hit)
169
+
144
170
  ### `index_usage`
145
171
 
146
172
  ```ruby
@@ -178,6 +204,8 @@ RubyPGExtras.locks
178
204
 
179
205
  This command displays queries that have taken out an exclusive lock on a relation. Exclusive locks typically prevent other operations on that relation from taking place, and can be a cause of "hung" queries that are waiting for a lock to be granted.
180
206
 
207
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#deadlocks)
208
+
181
209
  ### `all_locks`
182
210
 
183
211
  ```ruby
@@ -210,6 +238,8 @@ This command displays statements, obtained from `pg_stat_statements`, ordered by
210
238
 
211
239
  Typically, an efficient query will have an appropriate ratio of calls to total execution time, with as little time spent on I/O as possible. Queries that have a high total execution time but low call count should be investigated to improve their performance. Queries that have a high proportion of execution time being spent on synchronous I/O should also be investigated.
212
240
 
241
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#missing-indexes)
242
+
213
243
  ### `calls`
214
244
 
215
245
  ```ruby
@@ -230,6 +260,8 @@ RubyPGExtras.calls(args: { limit: 10 })
230
260
 
231
261
  This command is much like `pg:outliers`, but ordered by the number of times a statement has been called.
232
262
 
263
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#missing-indexes)
264
+
233
265
  ### `blocking`
234
266
 
235
267
  ```ruby
@@ -244,6 +276,8 @@ RubyPGExtras.blocking
244
276
 
245
277
  This command displays statements that are currently holding locks that other statements are waiting to be released. This can be used in conjunction with `pg:locks` to determine which statements need to be terminated in order to resolve lock contention.
246
278
 
279
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#deadlocks)
280
+
247
281
  ### `total_index_size`
248
282
 
249
283
  ```ruby
@@ -351,6 +385,26 @@ RubyPGExtras.unused_indexes(args: { min_scans: 20 })
351
385
 
352
386
  This command displays indexes that have < 50 scans recorded against them, and are greater than 5 pages in size, ordered by size relative to the number of index scans. This command is generally useful for eliminating indexes that are unused, which can impact write performance, as well as read performance should they occupy space in memory.
353
387
 
388
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#unused-indexes)
389
+
390
+ ### `null_indexes`
391
+
392
+ ```ruby
393
+
394
+ RubyPGExtras.null_indexes(args: { min_relation_size_mb: 10 })
395
+
396
+ oid | index | index_size | unique | indexed_column | null_frac | expected_saving
397
+ ---------+--------------------+------------+--------+----------------+-----------+-----------------
398
+ 183764 | users_reset_token | 1445 MB | t | reset_token | 97.00% | 1401 MB
399
+ 88732 | plan_cancelled_at | 539 MB | f | cancelled_at | 8.30% | 44 MB
400
+ 9827345 | users_email | 18 MB | t | email | 28.67% | 5160 kB
401
+
402
+ ```
403
+
404
+ This command displays indexes that contain `NULL` values. A high ratio of `NULL` values means that using a partial index excluding them will be beneficial in case they are not used for searching.
405
+
406
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#null-indexes)
407
+
354
408
  ### `seq_scans`
355
409
 
356
410
  ```ruby
@@ -373,11 +427,13 @@ RubyPGExtras.seq_scans
373
427
 
374
428
  This command displays the number of sequential scans recorded against all tables, descending by count of sequential scans. Tables that have very high numbers of sequential scans may be under-indexed, and it may be worth investigating queries that read from these tables.
375
429
 
430
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#missing-indexes)
431
+
376
432
  ### `long_running_queries`
377
433
 
378
434
  ```ruby
379
435
 
380
- RubyPGExtras.long_running_queries
436
+ RubyPGExtras.long_running_queries(args: { threshold: "200 milliseconds" })
381
437
 
382
438
 
383
439
  pid | duration | query
@@ -428,6 +484,8 @@ RubyPGExtras.bloat
428
484
 
429
485
  This command displays an estimation of table "bloat" – space allocated to a relation that is full of dead tuples, that has yet to be reclaimed. Tables that have a high bloat ratio, typically 10 or greater, should be investigated to see if vacuuming is aggressive enough, and can be a sign of high table churn.
430
486
 
487
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#bloat)
488
+
431
489
  ### `vacuum_stats`
432
490
 
433
491
  ```ruby
@@ -475,3 +533,19 @@ RubyPGExtras.mandelbrot
475
533
  ```
476
534
 
477
535
  This command outputs the Mandelbrot set, calculated through SQL.
536
+
537
+ ### `buffercache_stats`
538
+
539
+ This command shows the relations buffered in database share buffer, ordered by percentage taken. It also shows that how much of the whole relation is buffered.
540
+
541
+ ```ruby
542
+ RubyPGExtras.buffercache_stats(args: { limit: 10 })
543
+ ```
544
+
545
+ ### `buffercache_usage`
546
+
547
+ This command calculates how many blocks from which table are currently cached.
548
+
549
+ ```ruby
550
+ RubyPGExtras.buffercache_usage(args: { limit: 20 })
551
+ ```
@@ -8,20 +8,24 @@ module RubyPGExtras
8
8
  @@database_url = nil
9
9
 
10
10
  QUERIES = %i(
11
- bloat blocking cache_hit
11
+ bloat blocking cache_hit db_settings
12
12
  calls extensions table_cache_hit index_cache_hit
13
- index_size index_usage locks all_locks
13
+ index_size index_usage null_indexes locks all_locks
14
14
  long_running_queries mandelbrot outliers
15
15
  records_rank seq_scans table_indexes_size
16
16
  table_size total_index_size total_table_size
17
17
  unused_indexes vacuum_stats kill_all
18
+ buffercache_stats buffercache_usage
18
19
  )
19
20
 
20
21
  DEFAULT_ARGS = Hash.new({}).merge({
21
22
  calls: { limit: 10 },
22
23
  long_running_queries: { threshold: "500 milliseconds" },
23
24
  outliers: { limit: 10 },
24
- unused_indexes: { min_scans: 50 }
25
+ buffercache_stats: { limit: 10 },
26
+ buffercache_usage: { limit: 20 },
27
+ unused_indexes: { min_scans: 50 },
28
+ null_indexes: { min_relation_size_mb: 10 }
25
29
  })
26
30
 
27
31
  QUERIES.each do |query_name|
@@ -0,0 +1,13 @@
1
+ /* Calculates percentages of relations buffered in database share buffer */
2
+
3
+ SELECT
4
+ c.relname,
5
+ pg_size_pretty(count(*) * 8192) AS buffered,
6
+ round(100.0 * count(*) / (SELECT setting FROM pg_settings WHERE name = 'shared_buffers')::integer, 1) AS buffer_percent,
7
+ round(100.0 * count(*) * 8192 / pg_table_size(c.oid), 1) AS percent_of_relation
8
+ FROM pg_class c
9
+ INNER JOIN pg_buffercache b ON b.relfilenode = c.relfilenode
10
+ INNER JOIN pg_database d ON (b.reldatabase = d.oid AND d.datname = current_database())
11
+ GROUP BY c.oid,c.relname
12
+ ORDER BY 3 DESC
13
+ LIMIT %{limit};
@@ -0,0 +1,9 @@
1
+ /* Calculate how many blocks from which table are currently cached */
2
+
3
+ SELECT c.relname, count(*) AS buffers
4
+ FROM pg_class c
5
+ INNER JOIN pg_buffercache b ON b.relfilenode = c.relfilenode
6
+ INNER JOIN pg_database d ON (b.reldatabase = d.oid AND d.datname = current_database())
7
+ GROUP BY c.relname
8
+ ORDER BY 2 DESC
9
+ LIMIT %{limit};
@@ -0,0 +1,9 @@
1
+ /* Values of selected PostgreSQL settings */
2
+
3
+ SELECT name, setting, unit, short_desc FROM pg_settings
4
+ WHERE name IN (
5
+ 'max_connections', 'shared_buffers', 'effective_cache_size',
6
+ 'maintenance_work_mem', 'checkpoint_completion_target', 'wal_buffers',
7
+ 'default_statistics_target', 'random_page_cost', 'effective_io_concurrency',
8
+ 'work_mem', 'min_wal_size', 'max_wal_size'
9
+ );
@@ -0,0 +1,33 @@
1
+ /* Find indexes with a high ratio of NULL values */
2
+
3
+ SELECT
4
+ c.oid,
5
+ c.relname AS index,
6
+ pg_size_pretty(pg_relation_size(c.oid)) AS index_size,
7
+ i.indisunique AS unique,
8
+ a.attname AS indexed_column,
9
+ CASE s.null_frac
10
+ WHEN 0 THEN ''
11
+ ELSE to_char(s.null_frac * 100, '999.00%%')
12
+ END AS null_frac,
13
+ pg_size_pretty((pg_relation_size(c.oid) * s.null_frac)::bigint) AS expected_saving
14
+ FROM
15
+ pg_class c
16
+ JOIN pg_index i ON i.indexrelid = c.oid
17
+ JOIN pg_attribute a ON a.attrelid = c.oid
18
+ JOIN pg_class c_table ON c_table.oid = i.indrelid
19
+ JOIN pg_indexes ixs ON c.relname = ixs.indexname
20
+ LEFT JOIN pg_stats s ON s.tablename = c_table.relname AND a.attname = s.attname
21
+ WHERE
22
+ -- Primary key cannot be partial
23
+ NOT i.indisprimary
24
+ -- Exclude already partial indexes
25
+ AND i.indpred IS NULL
26
+ -- Exclude composite indexes
27
+ AND array_length(i.indkey, 1) = 1
28
+ -- Exclude indexes without null_frac ratio
29
+ AND coalesce(s.null_frac, 0) != 0
30
+ -- Larger than threshold
31
+ AND pg_relation_size(c.oid) > %{min_relation_size_mb} * 1024 ^ 2
32
+ ORDER BY
33
+ pg_relation_size(c.oid) * s.null_frac DESC;
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyPGExtras
4
- VERSION = "1.4.0"
4
+ VERSION = "1.6.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-pg-extras
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.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: 2021-01-26 00:00:00.000000000 Z
11
+ date: 2021-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -86,8 +86,11 @@ files:
86
86
  - lib/ruby-pg-extras/queries/all_locks.sql
87
87
  - lib/ruby-pg-extras/queries/bloat.sql
88
88
  - lib/ruby-pg-extras/queries/blocking.sql
89
+ - lib/ruby-pg-extras/queries/buffercache_stats.sql
90
+ - lib/ruby-pg-extras/queries/buffercache_usage.sql
89
91
  - lib/ruby-pg-extras/queries/cache_hit.sql
90
92
  - lib/ruby-pg-extras/queries/calls.sql
93
+ - lib/ruby-pg-extras/queries/db_settings.sql
91
94
  - lib/ruby-pg-extras/queries/extensions.sql
92
95
  - lib/ruby-pg-extras/queries/index_cache_hit.sql
93
96
  - lib/ruby-pg-extras/queries/index_size.sql
@@ -96,6 +99,7 @@ files:
96
99
  - lib/ruby-pg-extras/queries/locks.sql
97
100
  - lib/ruby-pg-extras/queries/long_running_queries.sql
98
101
  - lib/ruby-pg-extras/queries/mandelbrot.sql
102
+ - lib/ruby-pg-extras/queries/null_indexes.sql
99
103
  - lib/ruby-pg-extras/queries/outliers.sql
100
104
  - lib/ruby-pg-extras/queries/records_rank.sql
101
105
  - lib/ruby-pg-extras/queries/seq_scans.sql