ruby-pg-extras 1.3.1 → 1.5.3

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: 5d0df9d65eb4c50bca362f8d093b72eb62cd59b5137dd1cd8032837e8bcfbee8
4
- data.tar.gz: 2030a04032fd67df813e9699be68a26eb81d92de743e680e0a63145a9e48fa68
3
+ metadata.gz: 3de471f9f4d008d006000667b4b52d4e0d8aec0c5dc9ef55ce6045e5e8f96994
4
+ data.tar.gz: bb78196a09f0af1d7f4be623f1794223b3db074d19eb439e59670b8e960d06e1
5
5
  SHA512:
6
- metadata.gz: d66a0ba6f8d7baa5a509cb944e9e03a8d9da748b487e92165416f25e71561165f2259dab70f5d4e54bf603016dfb002610505175b67f9edf05ea4051a2f74260
7
- data.tar.gz: 7599de124bd7d1ab3bde751095fe1e4db1971acd9ac806b88f2ac53108617276571c8ffeffbbb3551cab67f1909e9311ad0bace7ec1519eda68da070379c81f1
6
+ metadata.gz: 7ed2d3f75a540b6e8b22db825a1479a53649ee3ddde59ca7783301f5e42d89f8a8c1d40e11b42a5f1340f3b72d866531a6878c57ccfb211f43ca00d21d82c177
7
+ data.tar.gz: 5f6618ededb729f9d085cfdc5c5c722065ccd8beee6cb191bdfc3e6e58700fa2468d0f5aa3f7829fc9d520d7fb66fe248d897d989fe7fec9c21896cb2234bdad
data/README.md CHANGED
@@ -85,6 +85,13 @@ RubyPGExtras.cache_hit(in_format: :raw) =>
85
85
  #<PG::Result:0x00007f75777f7328 status=PGRES_TUPLES_OK ntuples=2 nfields=2 cmd_tuples=2>
86
86
  ```
87
87
 
88
+ Some methods accept an optional `args` param allowing you to customize queries:
89
+
90
+ ```ruby
91
+ RubyPGExtras.long_running_queries(args: { threshold: "200 milliseconds" })
92
+
93
+ ```
94
+
88
95
  ## Available methods
89
96
 
90
97
  ### `cache_hit`
@@ -102,6 +109,8 @@ RubyPGExtras.cache_hit
102
109
 
103
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.
104
111
 
112
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#cache-hit)
113
+
105
114
  ### `index_cache_hit`
106
115
 
107
116
  ```ruby
@@ -118,6 +127,8 @@ RubyPGExtras.index_cache_hit
118
127
 
119
128
  The same as `cache_hit` with each table's indexes cache hit info displayed separately.
120
129
 
130
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#cache-hit)
131
+
121
132
  ### `table_cache_hit`
122
133
 
123
134
  ```ruby
@@ -134,6 +145,26 @@ RubyPGExtras.table_cache_hit
134
145
 
135
146
  The same as `cache_hit` with each table's cache hit info displayed seperately.
136
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
+
137
168
  ### `index_usage`
138
169
 
139
170
  ```ruby
@@ -171,6 +202,8 @@ RubyPGExtras.locks
171
202
 
172
203
  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.
173
204
 
205
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#deadlocks)
206
+
174
207
  ### `all_locks`
175
208
 
176
209
  ```ruby
@@ -185,7 +218,7 @@ This command displays all the current locks, regardless of their type.
185
218
 
186
219
  ```ruby
187
220
 
188
- RubyPGExtras.outliers
221
+ RubyPGExtras.outliers(args: { limit: 20 })
189
222
 
190
223
  qry | exec_time | prop_exec_time | ncalls | sync_io_time
191
224
  -----------------------------------------+------------------+----------------+-------------+--------------
@@ -203,11 +236,13 @@ This command displays statements, obtained from `pg_stat_statements`, ordered by
203
236
 
204
237
  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.
205
238
 
239
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#missing-indexes)
240
+
206
241
  ### `calls`
207
242
 
208
243
  ```ruby
209
244
 
210
- RubyPGExtras.calls
245
+ RubyPGExtras.calls(args: { limit: 10 })
211
246
 
212
247
  qry | exec_time | prop_exec_time | ncalls | sync_io_time
213
248
  -----------------------------------------+------------------+----------------+-------------+--------------
@@ -223,6 +258,8 @@ RubyPGExtras.calls
223
258
 
224
259
  This command is much like `pg:outliers`, but ordered by the number of times a statement has been called.
225
260
 
261
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#missing-indexes)
262
+
226
263
  ### `blocking`
227
264
 
228
265
  ```ruby
@@ -237,6 +274,8 @@ RubyPGExtras.blocking
237
274
 
238
275
  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.
239
276
 
277
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#deadlocks)
278
+
240
279
  ### `total_index_size`
241
280
 
242
281
  ```ruby
@@ -332,7 +371,7 @@ This command displays the total size of each table and materialized view in the
332
371
 
333
372
  ```ruby
334
373
 
335
- RubyPGExtras.unused_indexes
374
+ RubyPGExtras.unused_indexes(args: { min_scans: 20 })
336
375
 
337
376
  table | index | index_size | index_scans
338
377
  ---------------------+--------------------------------------------+------------+-------------
@@ -344,6 +383,26 @@ RubyPGExtras.unused_indexes
344
383
 
345
384
  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.
346
385
 
386
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#unused-indexes)
387
+
388
+ ### `null_indexes`
389
+
390
+ ```ruby
391
+
392
+ RubyPGExtras.null_indexes(args: { min_relation_size_mb: 10 })
393
+
394
+ oid | index | index_size | unique | indexed_column | null_frac | expected_saving
395
+ ---------+--------------------+------------+--------+----------------+-----------+-----------------
396
+ 183764 | users_reset_token | 1445 MB | t | reset_token | 97.00% | 1401 MB
397
+ 88732 | plan_cancelled_at | 539 MB | f | cancelled_at | 8.30% | 44 MB
398
+ 9827345 | users_email | 18 MB | t | email | 28.67% | 5160 kB
399
+
400
+ ```
401
+
402
+ 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.
403
+
404
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#null-indexes)
405
+
347
406
  ### `seq_scans`
348
407
 
349
408
  ```ruby
@@ -366,11 +425,13 @@ RubyPGExtras.seq_scans
366
425
 
367
426
  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.
368
427
 
428
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#missing-indexes)
429
+
369
430
  ### `long_running_queries`
370
431
 
371
432
  ```ruby
372
433
 
373
- RubyPGExtras.long_running_queries
434
+ RubyPGExtras.long_running_queries(args: { threshold: "200 milliseconds" })
374
435
 
375
436
 
376
437
  pid | duration | query
@@ -421,6 +482,8 @@ RubyPGExtras.bloat
421
482
 
422
483
  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.
423
484
 
485
+ [More info](https://pawelurbanek.com/postgresql-fix-performance#bloat)
486
+
424
487
  ### `vacuum_stats`
425
488
 
426
489
  ```ruby
@@ -8,9 +8,9 @@ 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
@@ -19,9 +19,10 @@ module RubyPGExtras
19
19
 
20
20
  DEFAULT_ARGS = Hash.new({}).merge({
21
21
  calls: { limit: 10 },
22
- long_running_queries: { interval: '5 seconds' },
22
+ long_running_queries: { threshold: "500 milliseconds" },
23
23
  outliers: { limit: 10 },
24
- unused_indexes: { min_scans: 50 }
24
+ unused_indexes: { min_scans: 50 },
25
+ null_indexes: { min_relation_size_mb: 10 }
25
26
  })
26
27
 
27
28
  QUERIES.each do |query_name|
@@ -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
+ );
@@ -9,6 +9,6 @@ FROM
9
9
  WHERE
10
10
  pg_stat_activity.query <> ''::text
11
11
  AND state <> 'idle'
12
- AND now() - pg_stat_activity.query_start > interval '%{interval}'
12
+ AND now() - pg_stat_activity.query_start > interval '%{threshold}'
13
13
  ORDER BY
14
14
  now() - pg_stat_activity.query_start DESC;
@@ -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.3.1"
4
+ VERSION = "1.5.3"
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.3.1
4
+ version: 1.5.3
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-22 00:00:00.000000000 Z
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -88,6 +88,7 @@ files:
88
88
  - lib/ruby-pg-extras/queries/blocking.sql
89
89
  - lib/ruby-pg-extras/queries/cache_hit.sql
90
90
  - lib/ruby-pg-extras/queries/calls.sql
91
+ - lib/ruby-pg-extras/queries/db_settings.sql
91
92
  - lib/ruby-pg-extras/queries/extensions.sql
92
93
  - lib/ruby-pg-extras/queries/index_cache_hit.sql
93
94
  - lib/ruby-pg-extras/queries/index_size.sql
@@ -96,6 +97,7 @@ files:
96
97
  - lib/ruby-pg-extras/queries/locks.sql
97
98
  - lib/ruby-pg-extras/queries/long_running_queries.sql
98
99
  - lib/ruby-pg-extras/queries/mandelbrot.sql
100
+ - lib/ruby-pg-extras/queries/null_indexes.sql
99
101
  - lib/ruby-pg-extras/queries/outliers.sql
100
102
  - lib/ruby-pg-extras/queries/records_rank.sql
101
103
  - lib/ruby-pg-extras/queries/seq_scans.sql