pgdexter 0.5.2 → 0.5.4
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/CHANGELOG.md +10 -0
- data/lib/dexter/indexer.rb +21 -10
- data/lib/dexter/query.rb +1 -1
- data/lib/dexter/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 037ac99e7dff1ac6edb6fddf8e85ae8357c6af25bc83dde1e5281f87c247ec4c
|
4
|
+
data.tar.gz: 1256486b21d6d6f91186a1a4e3ca0c1c39c7e318b26335d5cd86f82252b7ec42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4bc5d0355a53b867da9710a23edc7a898bd23f112ee93beee246b04584175609ac750f9819cb1be041b26f36db407363601e57a5cb8effb49214148c9ef688cb
|
7
|
+
data.tar.gz: a9019542cfefe04789426309834f7688cc59b8dea8d2d4f3d4559b349ae5bb72bf56de4bcd7ee54ec2483f41df85edec8dfd62f4e2e4db79d30117a874a02fd8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 0.5.4 (2024-04-03)
|
2
|
+
|
3
|
+
- Fixed issue with processing over 500 query fingerprints (introduced in 0.5.3)
|
4
|
+
- Require google-protobuf < 4
|
5
|
+
|
6
|
+
## 0.5.3 (2024-03-05)
|
7
|
+
|
8
|
+
- Fixed error with hypothetical index limit
|
9
|
+
- Fixed error with foreign tables
|
10
|
+
|
1
11
|
## 0.5.2 (2024-01-10)
|
2
12
|
|
3
13
|
- Added Docker image for `linux/arm64`
|
data/lib/dexter/indexer.rb
CHANGED
@@ -96,10 +96,16 @@ module Dexter
|
|
96
96
|
analyze_tables(tables) if tables.any? && (@analyze || @log_level == "debug2")
|
97
97
|
|
98
98
|
# create hypothetical indexes and explain queries
|
99
|
-
|
99
|
+
if tables.any?
|
100
|
+
# process in batches to prevent "hypopg: not more oid available" error
|
101
|
+
# https://hypopg.readthedocs.io/en/rel1_stable/usage.html#configuration
|
102
|
+
queries.select(&:candidate_tables).each_slice(500) do |batch|
|
103
|
+
create_hypothetical_indexes(batch)
|
104
|
+
end
|
105
|
+
end
|
100
106
|
|
101
107
|
# see if new indexes were used and meet bar
|
102
|
-
new_indexes = determine_indexes(queries,
|
108
|
+
new_indexes = determine_indexes(queries, tables)
|
103
109
|
|
104
110
|
# display and create new indexes
|
105
111
|
show_and_create_indexes(new_indexes, queries)
|
@@ -183,6 +189,8 @@ module Dexter
|
|
183
189
|
def create_hypothetical_indexes(queries)
|
184
190
|
candidates = {}
|
185
191
|
|
192
|
+
reset_hypothetical_indexes
|
193
|
+
|
186
194
|
# get initial costs for queries
|
187
195
|
calculate_plan(queries)
|
188
196
|
explainable_queries = queries.select { |q| q.plans.any? && q.high_cost? }
|
@@ -228,7 +236,9 @@ module Dexter
|
|
228
236
|
calculate_plan(explainable_queries)
|
229
237
|
end
|
230
238
|
|
231
|
-
|
239
|
+
queries.each do |query|
|
240
|
+
query.candidates = candidates
|
241
|
+
end
|
232
242
|
end
|
233
243
|
|
234
244
|
def find_columns(plan)
|
@@ -282,9 +292,8 @@ module Dexter
|
|
282
292
|
query_indexes
|
283
293
|
end
|
284
294
|
|
285
|
-
def determine_indexes(queries,
|
295
|
+
def determine_indexes(queries, tables)
|
286
296
|
new_indexes = {}
|
287
|
-
index_name_to_columns = candidates.invert
|
288
297
|
|
289
298
|
# filter out existing indexes
|
290
299
|
# this must happen at end of process
|
@@ -313,11 +322,11 @@ module Dexter
|
|
313
322
|
cost_savings2 = new_cost > 100 && new_cost2 < new_cost * savings_ratio
|
314
323
|
|
315
324
|
key = cost_savings2 ? 2 : 1
|
316
|
-
query_indexes = hypo_indexes_from_plan(
|
325
|
+
query_indexes = hypo_indexes_from_plan(query.candidates, query.plans[key], index_set)
|
317
326
|
|
318
327
|
# likely a bad suggestion, so try single column
|
319
328
|
if cost_savings2 && query_indexes.size > 1
|
320
|
-
query_indexes = hypo_indexes_from_plan(
|
329
|
+
query_indexes = hypo_indexes_from_plan(query.candidates, query.plans[1], index_set)
|
321
330
|
cost_savings2 = false
|
322
331
|
end
|
323
332
|
|
@@ -390,8 +399,8 @@ module Dexter
|
|
390
399
|
|
391
400
|
# TODO optimize
|
392
401
|
if @log_level.start_with?("debug")
|
393
|
-
query.pass1_indexes = hypo_indexes_from_plan(
|
394
|
-
query.pass2_indexes = hypo_indexes_from_plan(
|
402
|
+
query.pass1_indexes = hypo_indexes_from_plan(query.candidates, query.plans[1], index_set)
|
403
|
+
query.pass2_indexes = hypo_indexes_from_plan(query.candidates, query.plans[2], index_set)
|
395
404
|
end
|
396
405
|
end
|
397
406
|
end
|
@@ -595,7 +604,8 @@ module Dexter
|
|
595
604
|
columns_by_table.each do |table, cols|
|
596
605
|
# no reason to use btree index for json columns
|
597
606
|
cols.reject { |c| ["json", "jsonb"].include?(c[:type]) }.permutation(n) do |col_set|
|
598
|
-
|
607
|
+
index_name = create_hypothetical_index(table, col_set)
|
608
|
+
candidates[index_name] = col_set
|
599
609
|
end
|
600
610
|
end
|
601
611
|
end
|
@@ -612,6 +622,7 @@ module Dexter
|
|
612
622
|
information_schema.tables
|
613
623
|
WHERE
|
614
624
|
table_catalog = current_database()
|
625
|
+
AND table_type IN ('BASE TABLE', 'VIEW')
|
615
626
|
SQL
|
616
627
|
result.map { |r| r["table_name"] }
|
617
628
|
end
|
data/lib/dexter/query.rb
CHANGED
@@ -2,7 +2,7 @@ module Dexter
|
|
2
2
|
class Query
|
3
3
|
attr_reader :statement, :fingerprint, :plans
|
4
4
|
attr_writer :tables
|
5
|
-
attr_accessor :missing_tables, :new_cost, :total_time, :calls, :indexes, :suggest_index, :pass1_indexes, :pass2_indexes, :pass3_indexes, :candidate_tables, :tables_from_views
|
5
|
+
attr_accessor :missing_tables, :new_cost, :total_time, :calls, :indexes, :suggest_index, :pass1_indexes, :pass2_indexes, :pass3_indexes, :candidate_tables, :tables_from_views, :candidates
|
6
6
|
|
7
7
|
def initialize(statement, fingerprint = nil)
|
8
8
|
@statement = statement
|
data/lib/dexter/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pgdexter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: csv
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: google-protobuf
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "<"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "<"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: pg
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|