pg_query_analyzer 0.0.2 → 0.2

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.
Files changed (3) hide show
  1. data/README +46 -21
  2. data/lib/pg_query_analyzer.rb +15 -5
  3. metadata +1 -2
data/README CHANGED
@@ -1,42 +1,67 @@
1
1
  == PostgreSQL Query Analyzer for Rails
2
2
 
3
- Provides a PostgreSQL query analysis in your development logs.
3
+ Provides a PostgreSQL query analysis in your development logs.
4
4
 
5
+ This is useful for finding indexes that your database may benefit from. There
6
+ are alternatives available that guess which indexes may help and provide
7
+ example migrations, but I've found that performing a manual analysis using
8
+ tools like this typically leads to the best results.
5
9
 
6
- == Installation
7
10
 
8
- gem install pg_query_analyzer
11
+ == Instructions
9
12
 
10
- # config/enviroments/development.rb
13
+ Install the gem:
14
+ sudo gem install pg_query_analyzer
11
15
 
16
+ Require it development (config/enviroments/development.rb):
12
17
  config.gem "pg_query_analyzer"
13
18
 
19
+ You'll achieve the best results if you have your production database available
20
+ locally. If you're using Heroku (http://heroku.com) this means setting up your
21
+ development database to use PostgreSQL and running ("heroku db:pull").
14
22
 
15
- == Example
23
+ Restart your server ("script/server" or "touch tmp/restart.txt") and tail your
24
+ development log ("tail -f -n 100 log/development.log") to see the results. Note
25
+ the "total runtime", "cost", and "actual time" data points to locate long
26
+ running queries, as you might see in the second example provided below.
16
27
 
17
- Analyzing Car Load Execution Time:
28
+ Once you identify which queries are worth optimizing, you can generate and run
29
+ migrations to create the appropriate indexes, restart your server, and check
30
+ your logs to ensure that you're getting the results you expect. Once you're
31
+ finished, you can comment out or remove the config.gem call.
18
32
 
19
- Hash Join (cost=8.01..21.90 rows=6 width=2699)
20
- Hash Cond: (cars.group_id = group.id)
21
- -> Seq Scan on cars (cost=0.00..12.80 rows=280 width=2699)
22
- -> Hash (cost=8.00..8.00 rows=1 width=8)
23
- -> Hash Join (cost=3.90..8.00 rows=1 width=8)
24
- Hash Cond: (groups.id = contracts.group_id)
25
- -> Seq Scan on groups (cost=0.00..3.79 rows=79 width=4)
26
- -> Hash (cost=3.89..3.89 rows=1 width=4)
27
- -> Seq Scan on contracts (cost=0.00..3.89 rows=1 width=4)
28
- Filter: (user_id = 8)
33
+ Read more about database indexes here:
34
+ http://www.therailsway.com/2006/11/21/tracks-part-4
35
+ http://blog.evanweaver.com/articles/2007/02/12/table-indexes-in-rails/
36
+ http://github.com/eladmeidar/rails_indexes
29
37
 
30
38
 
31
- == Options
39
+ == Example One
32
40
 
33
- ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.explain_analyze = true
41
+ User Load (2.5ms) SELECT * FROM "users" WHERE ("users"."id" = 2) LIMIT 1
42
+ Analyzing User Load Execution Time: 0.002899
34
43
 
35
- Use ANALYZE to carry out the command and show the actual run times.
44
+ Limit (cost=0.00..8.27 rows=1 width=3734) (actual time=0.012..0.012 rows=1 loops=1)
45
+ Output: id, login, posts_count, followings_count, followers_count, created_at, updated_at,...
46
+ -> Index Scan using users_pkey on users (cost=0.00..8.27 rows=1 width=3734) (actual time=0.011..0.011 rows=1 loops=1)
47
+ Output: id, login, posts_count, followings_count, followers_count, created_at, updated_at...
48
+ Index Cond: (id = 2)
49
+ Total runtime: 0.052 ms
36
50
 
37
- ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.explain_verbose = true
38
51
 
39
- Use VERBOSE to show the full internal representation of the plan tree, rather than a summary.
52
+ == Example Two
53
+
54
+ FeedItem Load (5.1ms) SELECT * FROM "feed_items" WHERE ("feed_items".user_id = 2) ORDER BY feed_items.post_created_at DESC
55
+ Analyzing FeedItem Load Execution Time: 0.014169
56
+
57
+ Sort (cost=248.49..249.21 rows=290 width=32) (actual time=1.870..1.895 rows=290 loops=1)
58
+ Output: id, user_id, post_id, poster_id, post_created_at, created_at
59
+ Sort Key: post_created_at
60
+ Sort Method: quicksort Memory: 47kB
61
+ -> Seq Scan on feed_items (cost=0.00..236.62 rows=290 width=32) (actual time=0.015..1.735 rows=290 loops=1)
62
+ Output: id, user_id, post_id, poster_id, post_created_at, created_at
63
+ Filter: (user_id = 2)
64
+ Total runtime: 1.948 ms
40
65
 
41
66
 
42
67
  == Credits
@@ -1,13 +1,23 @@
1
1
  module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  class PostgreSQLAdapter < AbstractAdapter
4
- include CommonAnalyzer
4
+
5
+ @@analyzer_debug = 0..2
6
+ @@analyzer_warn = 3..7
5
7
 
6
- cattr_accessor :explain_analyze
7
- @@explain_analyze = nil
8
+ def select_logger time_spent, log
9
+ case time_spent
10
+ when @@analyzer_debug then @logger.debug(log)
11
+ when @@analyzer_warn then @logger.warn(log)
12
+ else @logger.fatal(log)
13
+ end
14
+ end
15
+
16
+ # ANALYZE carries out the command and show the actual run times.
17
+ @@explain_analyze = true # use nil to disable
8
18
 
9
- cattr_accessor :explain_verbose
10
- @@explain_verbose = nil
19
+ # VERBOSE shows the full plan tree, rather than a summary.
20
+ @@explain_verbose = true # use nil to disable
11
21
 
12
22
  private
13
23
 
metadata CHANGED
@@ -4,9 +4,8 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 0
8
7
  - 2
9
- version: 0.0.2
8
+ version: "0.2"
10
9
  platform: ruby
11
10
  authors:
12
11
  - Trevor Turk