Successfully reported this slideshow.
Your SlideShare is downloading. ×

[Srijan Wednesday Webinar] Easy Performance Wins for Your Rails App

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
Drupal and Elasticsearch
Drupal and Elasticsearch
Loading in …3
×

Check these out next

1 of 84 Ad

[Srijan Wednesday Webinar] Easy Performance Wins for Your Rails App

Download to read offline

Speaker: Aaron Cruz

In today’s webinar, we take a look at a how to improve the performance of your rails app. Our speaker today takes you through how to identify performance bottlenecks and understand the issues involved. He’ll also share quick tricks to solve issues and supercharge your rails app.

Speaker: Aaron Cruz

In today’s webinar, we take a look at a how to improve the performance of your rails app. Our speaker today takes you through how to identify performance bottlenecks and understand the issues involved. He’ll also share quick tricks to solve issues and supercharge your rails app.

Advertisement
Advertisement

More Related Content

Slideshows for you (20)

Advertisement

Similar to [Srijan Wednesday Webinar] Easy Performance Wins for Your Rails App (20)

More from Srijan Technologies (20)

Advertisement

Recently uploaded (20)

[Srijan Wednesday Webinar] Easy Performance Wins for Your Rails App

  1. 1. EASY RAILS PERFORMANCE WINS @mraaroncruz
  2. 2. AARON CRUZ!!!! @mraaroncruz
  3. 3. AARON CRUZ!!!! • I build bots for startups so they can better engage with their audience @mraaroncruz
  4. 4. AARON CRUZ!!!! • I build bots for startups so they can better engage with their audience • Been using Rails for ~7 years @mraaroncruz
  5. 5. WHERE AREYOU AT? • Beginner • Expert • Somewhere in the middle?
  6. 6. PROFILING 1st Win
  7. 7. MEASURE ALLTHETHINGS
  8. 8. ATTACKTHE LARGEST FIRST
  9. 9. HOWTO PROFILE
  10. 10. http://newrelic.com
  11. 11. WITH NEWRELICYOU CAN MONITOR
  12. 12. WITH NEWRELICYOU CAN MONITOR • Slow controller actions
  13. 13. WITH NEWRELICYOU CAN MONITOR • Slow controller actions • Slow SQL analysis
  14. 14. WITH NEWRELICYOU CAN MONITOR • Slow controller actions • Slow SQL analysis • Time spent in database calls
  15. 15. WITH NEWRELICYOU CAN MONITOR • Slow controller actions • Slow SQL analysis • Time spent in database calls • Performance of External Services
  16. 16. WITH NEWRELICYOU CAN MONITOR • Slow controller actions • Slow SQL analysis • Time spent in database calls • Performance of External Services • Much more...
  17. 17. IT’S FREE! 💵 🙏 😭
  18. 18. METRIC FU
  19. 19. CODE QUALITY GEMS
  20. 20. CODE QUALITY GEMS • Reek - finds code smells
  21. 21. CODE QUALITY GEMS • Reek - finds code smells • Cane - fails your build if code quality thresholds are not met
  22. 22. CODE QUALITY GEMS • Reek - finds code smells • Cane - fails your build if code quality thresholds are not met • Many more…
  23. 23. RACK MINIPROFILER
  24. 24. THE DATABASE 2nd Win
  25. 25. SOURCE OF MOST PERFORMANCE ISSUES 😿
  26. 26. MOST COMMON ISSUES
  27. 27. MOST COMMON ISSUES • Not using an index
  28. 28. MOST COMMON ISSUES • Not using an index • Loading too many records into memory (more an application design problem)
  29. 29. MOST COMMON ISSUES • Not using an index • Loading too many records into memory (more an application design problem) • Not being able to fit your index into memory
  30. 30. 1. USING AN INDEX
  31. 31. WHAT IS AN INDEX?
  32. 32. THE DOWNSIDE OF INDEXES
  33. 33. WHENTO ADD AN INDEX
  34. 34. HOWTO FIND BOTTLENECKS
  35. 35. SLOW QUERY LOG
  36. 36. MYSQL SLOW LOG
  37. 37. MYSQL SLOW LOG • /etc/mysql/my.cnf
  38. 38. MYSQL SLOW LOG • /etc/mysql/my.cnf
  39. 39. MYSQLDUMPSLOW
  40. 40. A FEW OTHERTOOLS • pt-query-digest • mysqlsla • Anemometer
  41. 41. POSTGRESQL SLOW LOG • Open the file postgresql.conf file • log_min_duration_statement = 100 • Save the file and reload • Watch the logs (/var/lib/pgsql/data/pg_log/)
  42. 42. EXPLAIN
  43. 43. users=# EXPLAIN ANALYZE SELECT username FROM users JOIN page_views p ON users.id = p.user_id WHERE users.friend_count = 50 LIMIT 100;
  44. 44. QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.42..4706.66 rows=100 width=11) (actual time=0.324..15.557 rows=100 loops=1) -> Nested Loop (cost=0.42..2172491.96 rows=46162 width=11) (actual time=0.323..15.543 rows=100 loops=1) -> Seq Scan on page_views p (cost=0.00..82430.44 rows=4496144 width=4) (actual time=0.004..0.839 rows=8179 loops=1) -> Index Scan using users_pkey on users (cost=0.42..0.45 rows=1 width=15) (actual time=0.002..0.002 rows=0 loops=8179) Index Cond: (id = p.user_id) Filter: (friend_count = 50) Rows Removed by Filter: 1 Planning time: 0.300 ms Execution time: 15.592 ms (9 rows)
  45. 45. CREATE INDEX ON page_views (user_id);
  46. 46. QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------- ----------- Limit (cost=0.43..122.29 rows=100 width=11) (actual time=0.049..0.316 rows=100 loops=1) -> Nested Loop (cost=0.43..56250.88 rows=46162 width=11) (actual time=0.048..0.303 rows=100 loops=1) -> Seq Scan on users (cost=0.00..20834.00 rows=10267 width=15) (actual time=0.020..0.172 rows=21 loops=1) Filter: (friend_count = 50) Rows Removed by Filter: 1110 -> Index Only Scan using page_views_user_id_idx on page_views p (cost=0.43..3.38 rows=7 width=4) (actual time=0.004..0.005 rows=5 loops=21) Index Cond: (user_id = users.id) Heap Fetches: 0 Planning time: 0.314 ms Execution time: 0.355 ms (10 rows)
  47. 47. 44TIMES FASTER 😹
  48. 48. 2. LOADINGTOO MUCH INTO MEMORY
  49. 49. N+1 QUERIES 3rd Win
  50. 50. #includes
  51. 51. class Post < ActiveRecord::Base belongs_to :author scope :published, -> { where(published: true) .order(published_at: :desc) } end class Author < ActiveRecord::Base has_many :posts end
  52. 52. posts = Post.published.limit(100) posts.each do |post| puts "#{post.title} - by #{post.author.name}" end # 1 query for articles # 100 queries for authors
  53. 53. Post.includes(:author).published.limit(100) # 2 queries # 1 for posts # 1 for authors
  54. 54. #joins
  55. 55. young_author_posts = Post.joins(:author) .where("authors.birth_year > ?", Date.today - 20.years) .order(:title) puts "Posts by young authors" young_author_posts.each |post| puts post.title end
  56. 56. TOOLS
  57. 57. # In ~/.zshrc, ~/.profile or ~/bashrc alias devlog=“tail -f log/development.log" USE ALIASES AND BASH FUNCTIONS
  58. 58. VIEW RENDERING 4th Win
  59. 59. YOU CAN SPEND A LOT OF TIME RENDERINGVIEWS
  60. 60. RACK MINIPROFILER
  61. 61. https://youtu.be/txT-PM8ujLM Miha Rekar at RubyC 2016 about flame graphs
  62. 62. YOURVIEW SHOULD BE DUMB 😜
  63. 63. REALLY DUMB 😜 😜 😜 😜 😜 😜 😜 😜 😜
  64. 64. VIEW CACHING 5th Win
  65. 65. 💵 CACHE IT! 💵 If you can’t speed it up
  66. 66. CACHING IN RAILS IS SOOOO EASY!
  67. 67. <% @products.each do |product| %> <% cache product do %> <%= render product %> <% end %> <% end %>
  68. 68. MODEL CACHING 6th Win
  69. 69. Rails.cache.fetch ISYOUR FRIEND
  70. 70. cache.write('today', 'Monday') cache.fetch('today') # => "Monday" cache.fetch('city') # => nil cache.fetch('city') do 'Duckburgh' end cache.fetch('city') # => "Duckburgh"
  71. 71. class Product < ActiveRecord::Base def competing_price Rails.cache.fetch([cache_key,“competing_price”], expires_in: 12.hours) do Competitor::API.find_price(id) end end end
  72. 72. JS AND CSS 7th Win
  73. 73. DELETE WHATYOU DON’T NEED
  74. 74. PROFILE NOW
  75. 75. FIXYOUR DATABASE
  76. 76. 💵 💵 💵 💵 💵 💵 💵
  77. 77. THANKYOU! @mraaroncruz

×