SlideShare ist ein Scribd-Unternehmen logo
1 von 47
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Ähnlich wie Optimización, rendimiento y escalabilidad en ActiveRecord

0157 genexus full_throttling
0157 genexus full_throttling0157 genexus full_throttling
0157 genexus full_throttlingGeneXus
 
0157 genexus full_throttling
0157 genexus full_throttling0157 genexus full_throttling
0157 genexus full_throttlingGeneXus
 
Rendimiento en aplicaciones web con Symfony2
Rendimiento en aplicaciones web con Symfony2Rendimiento en aplicaciones web con Symfony2
Rendimiento en aplicaciones web con Symfony2Asier Marqués
 
Define y desarrolla tu primera api
Define y desarrolla tu primera apiDefine y desarrolla tu primera api
Define y desarrolla tu primera apiCloudAppi
 
Rendimiento en magento
Rendimiento en magentoRendimiento en magento
Rendimiento en magentoOnestic
 
Manual script usuarios masivos
Manual script usuarios masivosManual script usuarios masivos
Manual script usuarios masivosYimy Pérez Medina
 
Configuración Script Usuarios Masivos Windows Server 2012 R2
Configuración Script Usuarios Masivos Windows Server 2012 R2Configuración Script Usuarios Masivos Windows Server 2012 R2
Configuración Script Usuarios Masivos Windows Server 2012 R2cyberleon95
 
Entendiendo el Triángulo de Hierro en Agile
Entendiendo el Triángulo de Hierro en AgileEntendiendo el Triángulo de Hierro en Agile
Entendiendo el Triángulo de Hierro en AgileJohnny Ordóñez
 
¿Cómo mantener tu javascript?: Buenas prácticas
¿Cómo mantener tu javascript?: Buenas prácticas¿Cómo mantener tu javascript?: Buenas prácticas
¿Cómo mantener tu javascript?: Buenas prácticasjaespinmora
 
Curso migración de aplicaciones nsl nk90 a tmp
Curso migración de aplicaciones nsl nk90 a tmpCurso migración de aplicaciones nsl nk90 a tmp
Curso migración de aplicaciones nsl nk90 a tmpEdgar Solis
 
Desarrollo sistemas web con PHP, HTML5, GOOGLE MAPS
Desarrollo sistemas web con PHP, HTML5, GOOGLE MAPSDesarrollo sistemas web con PHP, HTML5, GOOGLE MAPS
Desarrollo sistemas web con PHP, HTML5, GOOGLE MAPSArturo CUBA TORRES
 
Dynamics saturday madrid 2019 web api
Dynamics saturday madrid 2019   web apiDynamics saturday madrid 2019   web api
Dynamics saturday madrid 2019 web apiDemian Raschkovan
 
Charla OWASP
Charla OWASPCharla OWASP
Charla OWASPalexav8
 
PPTS Trabajo final-2.pptx proyecto de investigación
PPTS Trabajo final-2.pptx proyecto de investigaciónPPTS Trabajo final-2.pptx proyecto de investigación
PPTS Trabajo final-2.pptx proyecto de investigaciónJhiannAlcntaraContre
 
Buenas Prácticas de desarrollo en Ruby on Rails
Buenas Prácticas de desarrollo en Ruby on RailsBuenas Prácticas de desarrollo en Ruby on Rails
Buenas Prácticas de desarrollo en Ruby on RailsSergio Gil
 
Escalabilidad - Apache y MySQL
Escalabilidad - Apache y MySQLEscalabilidad - Apache y MySQL
Escalabilidad - Apache y MySQLLorena Fernández
 

Ähnlich wie Optimización, rendimiento y escalabilidad en ActiveRecord (20)

0157 genexus full_throttling
0157 genexus full_throttling0157 genexus full_throttling
0157 genexus full_throttling
 
0157 genexus full_throttling
0157 genexus full_throttling0157 genexus full_throttling
0157 genexus full_throttling
 
Rendimiento en aplicaciones web con Symfony2
Rendimiento en aplicaciones web con Symfony2Rendimiento en aplicaciones web con Symfony2
Rendimiento en aplicaciones web con Symfony2
 
Define y desarrolla tu primera api
Define y desarrolla tu primera apiDefine y desarrolla tu primera api
Define y desarrolla tu primera api
 
Rendimiento en magento
Rendimiento en magentoRendimiento en magento
Rendimiento en magento
 
Manual script usuarios masivos
Manual script usuarios masivosManual script usuarios masivos
Manual script usuarios masivos
 
¿Rails no escala?
¿Rails no escala?¿Rails no escala?
¿Rails no escala?
 
Configuración Script Usuarios Masivos Windows Server 2012 R2
Configuración Script Usuarios Masivos Windows Server 2012 R2Configuración Script Usuarios Masivos Windows Server 2012 R2
Configuración Script Usuarios Masivos Windows Server 2012 R2
 
Curso_slc.ppt
Curso_slc.pptCurso_slc.ppt
Curso_slc.ppt
 
Entendiendo el Triángulo de Hierro en Agile
Entendiendo el Triángulo de Hierro en AgileEntendiendo el Triángulo de Hierro en Agile
Entendiendo el Triángulo de Hierro en Agile
 
¿Cómo mantener tu javascript?: Buenas prácticas
¿Cómo mantener tu javascript?: Buenas prácticas¿Cómo mantener tu javascript?: Buenas prácticas
¿Cómo mantener tu javascript?: Buenas prácticas
 
Curso migración de aplicaciones nsl nk90 a tmp
Curso migración de aplicaciones nsl nk90 a tmpCurso migración de aplicaciones nsl nk90 a tmp
Curso migración de aplicaciones nsl nk90 a tmp
 
Desarrollo sistemas web con PHP, HTML5, GOOGLE MAPS
Desarrollo sistemas web con PHP, HTML5, GOOGLE MAPSDesarrollo sistemas web con PHP, HTML5, GOOGLE MAPS
Desarrollo sistemas web con PHP, HTML5, GOOGLE MAPS
 
Dynamics saturday madrid 2019 web api
Dynamics saturday madrid 2019   web apiDynamics saturday madrid 2019   web api
Dynamics saturday madrid 2019 web api
 
Charla OWASP
Charla OWASPCharla OWASP
Charla OWASP
 
PPTS Trabajo final-2.pptx proyecto de investigación
PPTS Trabajo final-2.pptx proyecto de investigaciónPPTS Trabajo final-2.pptx proyecto de investigación
PPTS Trabajo final-2.pptx proyecto de investigación
 
9.laravel
9.laravel9.laravel
9.laravel
 
Buenas Prácticas de desarrollo en Ruby on Rails
Buenas Prácticas de desarrollo en Ruby on RailsBuenas Prácticas de desarrollo en Ruby on Rails
Buenas Prácticas de desarrollo en Ruby on Rails
 
Escalabilidad - Apache y MySQL
Escalabilidad - Apache y MySQLEscalabilidad - Apache y MySQL
Escalabilidad - Apache y MySQL
 
Charla Mysql
Charla MysqlCharla Mysql
Charla Mysql
 

Kürzlich hochgeladen

Buenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxBuenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxFederico Castellari
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanamcerpam
 
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxJorgeParada26
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.FlorenciaCattelani
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxAlan779941
 
investigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIinvestigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIhmpuellon
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estossgonzalezp1
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...JohnRamos830530
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21mariacbr99
 
Guia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos BasicosGuia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos BasicosJhonJairoRodriguezCe
 
redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativanicho110
 

Kürzlich hochgeladen (11)

Buenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxBuenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptx
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
 
investigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIinvestigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXI
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21
 
Guia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos BasicosGuia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos Basicos
 
redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativa
 

Optimización, rendimiento y escalabilidad en ActiveRecord

  • 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
  • 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