Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Measuring Website Performance With New Relic

Measuring Website Performance With New Relic

Slides from a hands-on workshop where attendees built a Node app and then monitored its performance using New Relic.

Erin Dees

May 18, 2016
Tweet

More Decks by Erin Dees

Other Decks in Programming

Transcript

  1. <% $db = connect_to_database('db.example.com', 'password'); $rows = $db.query('select * from

    movies;'); %> <h1>My awesome movies</h1> <% for i in (0...$rows.count) do %> <p>Movie no. <%= i %> is <%= $rows[i][0] %></p> <% end %>
  2. APM

  3. FIND ALL MOVIES # SELECT * FROM movies; title |

    year | language ---------+------+----------- OMG CAT | 2005 | Finnish LOL DOG | 2010 | Esperanto (2 rows)
  4. ONLY THE ONES IN ESPERANTO # SELECT * FROM movies

    WHERE language = 'Esperanto'; title | year | language ---------+------+----------- LOL DOG | 2010 | Esperanto (1 row)
  5. WHAT KIND OF REVIEWS DID THIS MOVIE GET? # SELECT

    stars FROM reviews WHERE movie = 'LOL DOG'; stars ------- 5 1 (2 rows)
  6. WHAT KIND OF REVIEWS DID THIS MOVIE GET? # SELECT

    stars FROM movies WHERE title = 'LOL DOG'; stars ------- 5,1 (1 row)
  7. WHAT KIND OF REVIEWS DID THIS MOVIE GET? # SELECT

    * FROM reviews WHERE movie_id = 2; reviewer | stars | movie_id -----------------+-------+---------- Siskeltron 4000 | 5 | 2 Ebert-bot | 1 | 2 (2 rows)
  8. ] 1

  9. ] 1

  10. ] 2

  11. ] 2

  12. ] 3

  13. ] 3

  14. 3

  15. ] 4

  16. ] 4

  17. ] 5

  18. ] 5

  19. 5

  20. ] 6

  21. ] 6

  22. 6

  23. Items Steps Total 2 1 1 3 2 + 1

    3 4 3 + 2 + 1 6 5 4 + 3 + 2 + 1 10 6 5 + 4 + 3 + 2 + 1 15
  24. Number of steps needed for n items = 1 +

    2 + 3 + … + (n - 1) = ½ ⨉ n ⨉ (n − 1) = ½n2 − ½n

  25. What order of complexity is this? ½n2 − ½n ½n2

    − ½n ½n2 − ½n so, it's O(n2)
  26. MOVIES AND REVIEWS # SELECT * FROM movies; id |

    title | year | language ----+---------+------+----------- 1 | OMG CAT | 2005 | Finnish 2 | LOL DOG | 2010 | Esperanto (2 rows) # SELECT * FROM reviews; reviewer | stars | movie_id -----------------+-------+---------- Siskeltron 4000 | 5 | 2 Ebert-bot | 1 | 2 Ebert-bot | 4 | 1 (3 rows)
  27. MOVIES AND REVIEWS movies = db.query('SELECT * FROM movies;') movies.each

    do |movie| puts movie.title reviews = db.query('SELECT * FROM REVIEWS WHERE movie_id = ' + movie.id) reviews.each do |review| puts review.reviewer + ' gave it ' + review.stars + ' star(s)' end end
  28. MOVIES AND REVIEWS movies = db.query('SELECT * FROM movies;') movies.each

    do |movie| puts movie.title reviews = db.query('SELECT * FROM REVIEWS WHERE movie_id = ' + movie.id) reviews.each do |review| puts review.reviewer + ' gave it ' + review.stars + ' star(s)' end end
  29. MOVIES AND REVIEWS movies = db.query('SELECT * FROM movies;') movies.each

    do |movie| puts movie.title reviews = db.query('SELECT * FROM REVIEWS WHERE movie_id = ' + movie.id) reviews.each do |review| puts review.reviewer + ' gave it ' + review.stars + ' star(s)' end end
  30. MOVIES AND REVIEWS movies = db.query('SELECT * FROM movies;') movies.each

    do |movie| puts movie.title reviews = db.query('SELECT * FROM REVIEWS WHERE movie_id = ' + movie.id) reviews.each do |review| puts review.reviewer + ' gave it ' + review.stars + ' star(s)' end end
  31. MOVIES AND REVIEWS movies = db.query('SELECT * FROM movies;') movies.each

    do |movie| puts movie.title reviews = db.query('SELECT * FROM REVIEWS WHERE movie_id = ' + movie.id) reviews.each do |review| puts review.reviewer + ' gave it ' + review.stars + ' star(s)' end end
  32. MOVIES AND REVIEWS movies = db.query('SELECT * FROM movies;') movies.each

    do |movie| puts movie.title reviews = db.query('SELECT * FROM REVIEWS WHERE movie_id = ' + movie.id) reviews.each do |review| puts review.reviewer + ' gave it ' + review.stars + ' star(s)' end end
  33. Number of queries needed for n movies: = 1 query

    to get the list of movies + (n movies ⨉ 1 query for a single movie’s reviews) = n + 1

  34. THINGS THAT HAPPEN FOR EVERY MOVIE: ▸ Your app builds

    a SQL query ▸ Your app sends the query over the network ▸ The database parses the query ▸ The database finds the answers on disk ▸ The database formats a SQL response ▸ The database sends the response over the network ▸ Your app decodes the response
  35. N + 1 QUERIES TO LOAD THE PAGE 1000 movies

    ⨉ 1 review query for each movie = 1000 queries + 1 for the list of movie titles = 1001 queries
  36. TIME FOR 1 PAGE LOAD Assume 0.01 second for a

    single query 1001 queries ⨉ 0.01 seconds for each query = 10.01 seconds to show your web page
  37. THINGS THAT HAPPEN FOR EVERY MOVIE JUST ONCE: ▸ Your

    app builds a SQL query ▸ Your app sends the query over the network ▸ The database parses the query ▸ The database finds the answers on disk ▸ The database formats a SQL response ▸ The database sends the response over the network ▸ Your app decodes the response
  38. THESE BITS ARE SLOWER: ▸ Your app builds a SQL

    query ▸ Your app sends the query over the network ▸ The database parses the query ▸ The database finds the answers on disk ▸ The database formats a SQL response ▸ The database sends the response over the network ▸ Your app decodes the response
  39. TIME FOR 1 PAGE LOAD (WITH ONE BIG QUERY) Assume

    the “give me everything” query takes: 100 times longer ⨉ 0.01 seconds = 1 second to show your web page …a 10x speedup!
  40. MOVIES AND REVIEWS # SELECT * FROM movies; id |

    title | year | language ----+---------+------+----------- 1 | OMG CAT | 2005 | Finnish 2 | LOL DOG | 2010 | Esperanto (2 rows) # SELECT * FROM reviews; reviewer | stars | movie_id -----------------+-------+---------- Siskeltron 4000 | 5 | 2 Ebert-bot | 1 | 2 Ebert-bot | 4 | 1 (3 rows)
  41. MOVIES THAT HAVE REVIEWS # SELECT reviews.reviewer, reviews.stars, movies.title FROM

    reviews INNER JOIN movies ON (reviews.movie_id = movies.id); reviewer | stars | title -----------------+-------+--------- Siskeltron 4000 | 5 | LOL DOG Ebert-bot | 1 | LOL DOG Ebert-bot | 4 | OMG CAT (3 rows)
  42. MOVIES THAT HAVE REVIEWS # SELECT reviews.reviewer, reviews.stars, movies.title FROM

    reviews INNER JOIN movies ON (reviews.movie_id = movies.id); reviewer | stars | title -----------------+-------+--------- Siskeltron 4000 | 5 | LOL DOG Ebert-bot | 1 | LOL DOG Ebert-bot | 4 | OMG CAT (3 rows)
  43. MOVIES THAT HAVE REVIEWS # SELECT reviews.reviewer, reviews.stars, movies.title FROM

    reviews INNER JOIN movies ON (reviews.movie_id = movies.id); reviewer | stars | title -----------------+-------+--------- Siskeltron 4000 | 5 | LOL DOG Ebert-bot | 1 | LOL DOG Ebert-bot | 4 | OMG CAT (3 rows)
  44. MOVIES THAT HAVE REVIEWS # SELECT reviews.reviewer, reviews.stars, movies.title FROM

    reviews INNER JOIN movies ON (reviews.movie_id = movies.id); reviewer | stars | title -----------------+-------+--------- Siskeltron 4000 | 5 | LOL DOG Ebert-bot | 1 | LOL DOG Ebert-bot | 4 | OMG CAT (3 rows)
  45. MOVIES THAT HAVE REVIEWS # SELECT reviews.reviewer, reviews.stars, movies.title FROM

    reviews INNER JOIN movies ON (reviews.movie_id = movies.id); reviewer | stars | title -----------------+-------+--------- Siskeltron 4000 | 5 | LOL DOG Ebert-bot | 1 | LOL DOG Ebert-bot | 4 | OMG CAT (3 rows)
  46. RAILS WITH AN N+1 class Movie < ActiveRecord::Base has_many reviews

    end movies = Movie.all # ...then, get reviews for each movie...
  47. N+1 FIXED class Movie < ActiveRecord::Base has_many reviews end movies

    = Movie.includes(:reviews) # ...then, get reviews for each movie...
  48. LEGALESE This document and the information herein (including any information

    that may be incorporated by reference) is provided for informational purposes only and should not be construed as an offer, commitment, promise or obligation on behalf of New Relic, Inc. (“New Relic”) to sell securities or deliver any product, material, code, functionality, or other feature. Any information provided hereby is proprietary to New Relic and may not be replicated or disclosed without New Relic’s express written permission. Such information may contain forward-looking statements within the meaning of federal securities laws. Any statement that is not a historical fact or refers to expectations, projections, future plans, objectives, estimates, goals, or other characterizations of future events is a forward-looking statement. These forward-looking statements can often be identified as such because the context of the statement will include words such as “believes,” “anticipates,” “expects” or words of similar import. Actual results may differ materially from those expressed in these forward-looking statements, which speak only as of the date hereof, and are subject to change at any time without notice. Existing and prospective investors, customers and other third parties transacting business with New Relic are cautioned not to place undue reliance on this forward-looking information. The achievement or success of the matters covered by such forward-looking statements are based on New Relic’s current assumptions, expectations, and beliefs and are subject to substantial risks, uncertainties, assumptions, and changes in circumstances that may cause the actual results, performance, or achievements to differ materially from those expressed or implied in any forward-looking statement. Further information on factors that could affect such forward-looking statements is included in the filings we make with the SEC from time to time. Copies of these documents may be obtained by visiting New Relic’s Investor Relations website at ir.newrelic.com or the SEC’s website at www.sec.gov. New Relic assumes no obligation and does not intend to update these forward-looking statements, except as required by law. New Relic makes no warranties, expressed or implied, in this document or otherwise, with respect to the information provided.