• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Optimización, rendimiento y escalabilidad en ActiveRecord
 

Optimización, rendimiento y escalabilidad en ActiveRecord

on

  • 2,585 views

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"

Statistics

Views

Total Views
2,585
Views on SlideShare
2,560
Embed Views
25

Actions

Likes
2
Downloads
32
Comments
0

3 Embeds 25

http://www.spainrb.org 13
http://coderwall.com 7
http://www.slideshare.net 5

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Optimización, rendimiento y escalabilidad en ActiveRecord Optimización, rendimiento y escalabilidad en ActiveRecord Presentation Transcript

    • Conferencia Rails 2008 Optimización, rendimiento y escalabilidad en ActiveRecord Emili Parreño www.eparreno.com
    • Introducción optimizar != escalar Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • 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
    • 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
    • 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
    • Introducción Optimización => Aumentar el rendimiento Escalabilidad => Mantener el rendimiento Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • Tareas en background Opciones: - script/runner - daemon_generator - BackgrounDRB - Spawn - Starling ... Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • Í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
    • Índices Evitar consultas que recorran toda la tabla (*) Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • Í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
    • Í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
    • Í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
    • Í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
    • Í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
    • Í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
    • 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
    • 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
    • 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
    • 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
    • Herramientas Query Reviewer Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • Herramientas Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • Herramientas New Relic Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • Herramientas Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • Herramientas Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • Herramientas Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • Herramientas
    • Herramientas Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • 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
    • Resumen “Constraints force creativity.” Getting Real - 37 Signals Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com
    • Emili Parreño - www.eparreno.com Optimización, rendimiento y escalabilidad en AR Emili Parreño - www.eparreno.com