Your SlideShare is downloading. ×
Optimización, rendimiento y escalabilidad en ActiveRecord
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Optimización, rendimiento y escalabilidad en ActiveRecord

1,547

Published on

Presentación de la ponencia que realicé en la conferencia Rails 2008 titulada: "Optimización, rendimiento y escalabilidad en ActiveRecord"

Presentación de la ponencia que realicé en la conferencia Rails 2008 titulada: "Optimización, rendimiento y escalabilidad en ActiveRecord"

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,547
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
33
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Conferencia Rails 2008 Optimización, rendimiento y escalabilidad en ActiveRecord Emili Parreño www.eparreno.com
  • 2. Introducción optimizar != escalar Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 3. Introducción “La optimización es el proceso de búsqueda de la mejor manera de realizar un proceso, con respecto a uno o más recursos, que pueden ser: tiempo de ejecución, uso de memoria, uso de CPU...” Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 4. Introducción “La escalabilidad es la propiedad deseable de un sistema, que indica su habilidad para, o bien manejar el crecimiento continuo de trabajo de manera fluida, o bien para estar preparado para hacerse más grande con un impacto mínimo en el redimiento.” Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 5. Introducción “El rendimiento es la relación entre los resultados obtenidos y los recursos utilizados.” e = resultados / recursos Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 6. Introducción Optimización => Aumentar el rendimiento Escalabilidad => Mantener el rendimiento Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 7. Reducir el tamaño de las consultas Consulta ineficiente: def index @users = User.find(:all, :limit => 20) end SELECT * FROM users LIMIT 0,10 ORDER BY id desc Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 8. Reducir el tamaño de las consultas Optimización: def index @users = User.find(:all, :select => “id, name”, :limit => 20) end Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 9. Reducir el tamaño de las consultas Benchmark (75000 registros): #1 User.find(:all, :limit => 20) #2 User.find(:all, :limit => 20, :select => “id, name, surname”) user system total real #1 0.000000 0.000000 0.000000 ( 0.000927) #2 0.000000 0.000000 0.000000 ( 0.000552) Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 10. Reducir el tamaño de las consultas Benchmark (75000 registros): #1 User.find(:all) #2 User.find(:all, :select => “id, name, surname”) user system total real #1 6.520000 0.350000 6.870000 ( 7.945950) #2 2.140000 0.040000 2.180000 ( 2.931969) Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 11. Contadores Categorias - Ruby (1345) - Rails (2389) - Testing (345) - Performance (34) for cat in @categories puts “#{cat.name} (#{cat.posts.count})” end => select count(*) from posts where category_id = id 500.000 posts x 4 categorias = 2.000.000 de registros consultados!! Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 12. Contadores Optimización: class Post < ActiveRecord::Base belongs_to :category, :counter_cache => true end create_table :categories do |t| t.string :name ... t.integer :posts_count, :default => 0 t.timestamps end Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 13. Contadores for cat in @categories puts “#{cat.name} (#{cat.posts_count})” end Evitamos los 2.000.000 de registros recorridos en 4 consultas Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 14. Eager Loading Consulta ineficiente: def index @posts = Post.find(:all, :limit => 10) end for post in @posts puts “Titulo:” + post.title puts “Autor:” + post.user.name end => 1+10 querys Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 15. Eager Loading Optimización: def index @posts = Post.find(:all, :limit => 10, :include => :user) end for post in @posts puts “Titulo:” + post.title puts “Autor:” + post.user.name end => 1+1 querys Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 16. Eager Loading Optimización: def index @posts = Post.find(:all, :limit => 10, :select => “posts.id, posts.title”, :include => :user) end for post in @posts puts “Titulo:” + post.title puts “Autor:” + post.user.name end => 1+1 querys Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 17. Eager Loading Problema: Podríamos hacer... def index @posts = Post.find(:all, :limit => 10, :select => “posts.id, posts.title, user.id, user.name”, :include => :user) end Pero no funciona :( Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 18. Eager Loading Optimización: def index @posts = Post.find(:all, :limit => 10, :select => quot;posts.title, users.name AS user_namequot;, :joins => [:user]) end for post in @posts puts “Titulo:” + post.title puts “Autor:” + post.user_name end => 1 query Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 19. Eager Loading Consulta ineficiente: def index @post = Post.find(params[:id]) end for comment in @post.comments puts comment.body puts “Autor:” + comment.user.name end => 1 query para el post => 1 query para los comentarios => N querys para los usuarios Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 20. Eager Loading Optimización: def index @post = Post.find(params[:id]) @comments = @post.comments.find(:all, :include => :user) end for comment in @comments puts comment.body puts “Autor:” + comment.user.name end => 1 query para el post => 1 query para los comentarios => 1 query para los usuarios Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 21. Eager Loading Optimización: def index @post = Post.find(params[:id], :include => [:user, :comments]) end puts “Post:” + @post.body puts “Autor:” + @post.user.name for comment in @post.comments puts “Comentario:” + comment.body end => 3 querys Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 22. Tareas en background Si con lo anterior no es suficiente para optimizar una consulta siempre nos queda el Método de toda la vida: User.find_by_sql(SELECT id, name, surname WHERE user.name = 'Pepe') Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 23. Tareas en background Sacar tareas fuera del ciclo del request - Envío de emails - Cálculos - Tareas de mantenimiento ... Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 24. Tareas en background Opciones: - script/runner - daemon_generator - BackgrounDRB - Spawn - Starling ... Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 25. Índices Consulta ineficiente: @users = User.find(:all, :conditions => “name = Pepe”) Recorre toda la tabla Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 26. Índices Evitar consultas que recorran toda la tabla (*) Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 27. Índices Restricciones: - No utilizar índices en columnas que se actualizan frecuentemente - No utilizar índices en columnas con poca variación (p.e. booleanos) - No utilizar Índices en tablas pequeñas - No utilizar índices muy grandes Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 28. Índices Optimización Añadimos un índice en el campo “name” con una migración add_index :users, :name Benchmark 75000 usuarios @users = User.find(:all, :conditions => “name = Pepe”) user system total real #1 0.010000 0.000000 0.010000 ( 0.631635) #2 0.010000 0.000000 0.010000 ( 0.015232) Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 29. Índices Podemos añadir índices multicolumna add_index :users, [:name, :city] No permite índices de más de 1024 bytes En UTF-8 cada carácter necesita 3 bytes (256+256)*3 = 1536 bytes 1536 x 500000 = 768 MB Limitar el tamaño de los campos t.column :login, :string, :limit => 10, :null => false Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 30. Índices Definir la longitud del índice def self.up execute quot;CREATE INDEX full_name ON users (name(10), surname(10))quot; end Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 31. Índices “La regla de la izquierda” Si se utilizan índices multicolumna en las cláusulas WHERE, hay que incluir siempre de izquierda a derecha las columnas indexadas add_index :users, [:name, :surname, :city] SELECT * from users WHERE city = ʻMadridʼ SELECT * from users WHERE name = ʻPepeʼ SELECT * from users WHERE name = ʻPepeʼ AND surname = ʻLopezʼ Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 32. Índices y ordenación Podemos añadir índices multicolumna para ordenar add_index :users, [:city, :created_at] Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 33. MyISAM vs InnoDB Benchmark 75000 usuarios User.count user system total real #1 0.000000 0.000000 0.000000 ( 0.663447) (InnoDB) #2 0.010000 0.000000 0.010000 ( 0.000688) (MyISAM) User.find(:all) user system total real #1 11.040000 0.660000 11.700000 ( 12.585430) (InnoDB) #2 11.070000 0.670000 11.740000 ( 12.124938) (MyISAM) User.find(:all, :conditions => “name = ‘Pepe’”) user system total real #1 0.010000 0.000000 0.010000 ( 0.015615) (InnoDB) #2 0.000000 0.000000 0.000000 ( 0.018247) (MyISAM) Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 34. MyISAM vs InnoDB Benchmark 270.000 posts Post.find_by_category_id(14) #1 0.000000 0.000000 0.000000 ( 0.000865) (InnoDB) #2 0.000000 0.000000 0.000000 ( 0.001019) (MyISAM) Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 35. MyISAM vs InnoDB Benchmark 270.000 posts Post.find(:all, :conditions => 'body LIKE “Hello”’) user system total real #1 0.000000 0.000000 0.000000 ( 3.471458) (InnoDB) #2 0.000000 0.000000 0.000000 ( 3.371270) (MyISAM) Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 36. Herramientas Antes de empezar a optimizar: rellenar la base de datos - populator - db-populate - babel ... Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 37. Herramientas Query Reviewer Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 38. Herramientas Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 39. Herramientas New Relic Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 40. Herramientas Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 41. Herramientas Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 42. Herramientas Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 43. Herramientas
  • 44. Herramientas Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 45. Resumen • Optimizar es un proceso necesario y contínuo • Optimizar a medida que desarrollamos o cuando refactorizamos • Utilizar herramientas para encontrar “slow querys” Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 46. Resumen “Constraints force creativity.” Getting Real - 37 Signals Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
  • 47. Emili Parreño - www.eparreno.com Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com

×