Maior performance no seu sistema
com o uso adequado de
ORM em Rails
Maior performance no seu sistema com o uso adequado de orm em rails
Vamos usar outra linguagem
Ruby é lento
Vamos fragmentar o sistema
Precisamos reescrever do zero
Será que o problema é a
linguagem ou o framework?
Ou não estamos usando
eles de forma adequada?
ORM
EM
RAILS
Object
Relational
Mapping
Rails nos oferece
Active
Record
Ele é um Pattern!
Martin Fowler
Order
Customer
Order Items
Product
Shipping Company
Delivery
>Order.create(customer:...)
>Order.find(1).customer.name
>Order.find_by(customer:1).order_items.count
>Order.all
class Customer < ApplicationRecord
end
class Delivery < ApplicationRecord
belongs_to :shipping_company
belongs_to :ordem_item
end
class Order < ApplicationRecord
belongs_to :customer
has_many :order_items
end
class OrderItem < ApplicationRecord
belongs_to :order
belongs_to :product
has_one :delivery
end
class Product < ApplicationRecord
end
class ShippingCompany < ApplicationRecord
end
Order Load (1.0ms) SELECT "orders".* FROM
"orders" LIMIT $1 [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Order id: 1,
customer_id: 2, status: "ENTREGUE", ...]>
<table>
<thead>
<tr>
<th>Id</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<% @orders.each do |order| %>
<tr>
<td><%= order.id %></td>
<td><%= order.status %></td>
</tr>
<% end %>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Customer</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<% @orders.each do |order| %>
<tr>
<td><%= order.customer.name %></td>
<td><%= order.status %></td>
</tr>
<% end %>
</tbody>
</table>
Para 10.000 orders, até 10.001 consultas ao banco
(Queries N+1)
def index
@orders = Order.all
end
def index
@orders = Order.all.includes(:customer)
end
2 consultas ao banco de dados
def index
@orders = Order.all.joins(:customer).includes(:customer)
end
1 consulta ao banco de dados
Default
16171ms
9408ms
9574ms
9783ms
17361ms
19387ms
13.6s
Qual melhor estratégia?
Include
1490ms
1440ms
1844ms
1581ms
1555ms
1969ms
1.6s
Join + Include
2044ms
2168ms
1536ms
1903ms
1978ms
1668ms
1.8s
+ db index
1579ms
1653ms
1575ms
1556ms
1613ms
1564ms
1.5s
Como coletar
essas métricas?
Uso do log do rails server
Maior performance no seu sistema com o uso adequado de orm em rails
Application
Performance
Management (APM)
Maior performance no seu sistema com o uso adequado de orm em rails
15ms
1ms
https://github.com/newrelic/rpm
Maior performance no seu sistema com o uso adequado de orm em rails
Porque esses
problemas ocorrem ?
SOLUÇÃO CRESCE !
● FEATURES COMPLEXAS
O TIME CRESCE !!!
● MAPEAMENTOS EQUIVOCADOS
● MAU USO DE NAVEGAÇÃO
ENTRE OBJETOS
● MODELAGEM CONFUSA
Como evitar
esses problemas ?
Bullet
https://github.com/flyerhzm/bullet
DB Query Matchers
https://github.com/brigade/db-query-matchers
teste A
teste B
teste C
teste D
teste E
teste F
teste G
teste H
teste I
teste J
teste K
teste L
require 'rails_helper'
feature 'orders index' do
scenario 'list all' do
expect { visit('/orders') }.to make_database_queries(count: 3)
end
scenario 'list all' do
expect { visit('/orders_include') }.to make_database_queries(count: 2)
end
scenario 'list all' do
expect { visit('/orders_join') }.to make_database_queries(count: 1)
end
end
Maior performance no seu sistema com o uso adequado de orm em rails
expect { }.to_not make_database_queries(matching: /UPDATE/)
expect { }.to_not make_database_queries
expect { }.to make_database_queries(count: 1)
expect { }.to make_database_queries(count: 0..3)
expect { }.to_not make_database_queries(manipulative: true)
(INSERT, UPDATE, DELETE)
Boas
Práticas
Uso de Scope
def index_with_join
@orders = Order.all.joins(:customer).includes(:customer)
end
Controller
class Order < ApplicationRecord
belongs_to :customer
has_many :order_items
scope :all_with_customer, -> {Order.all.joins(:customer).includes(:customer)}
end
Model
def index_with_join
@orders = Order.all_with_customer
end
Controller
Evite...
scope :all_with_customer, -> {
Order.all.includes(:customer).order(:status)}
Ordenação
default_scope :active, -> {Customer.where(active:true)}Default
scope :closed, -> {Order.where(status:‘closed’)
.where(‘total_amount >= ?’, 10.0)}
Itens
Implícitos
scope :closed, -> do
find_by_sql <<-SQL
select * from orders where status = ‘closed’
SQL
end
SQL puro
Queries customizadas com
Mapeamento Alternativos
class SummaryOrder < ApplicationRecord
self.table_name = "orders"
scope :all_summarized, -> {
select('orders.id')
.select('customers.name')
.select('orders.status')
.select('count(order_items.id) as items_quantity')
.joins('left join customers on orders.customer_id = customers.id')
.joins('right join order_items on order_items.order_id = orders.id')
.group('orders.id, customers.name, orders.status')
}
end
...
<tr>
<th>Customer</th>
<th>Status</th>
<th>Quantity of Items</th>
</tr>
...
<% @summary_orders.each do |summary_order| %>
<tr>
<td><%= summary_order.name %></td>
<td><%= summary_order.status %></td>
<td><%= summary_order.items_quantity %></td>
</tr>
<% end %>
...
class SummaryOrder
attr_accessor :id,
:name,
:status,
:items_quantity
end
Maior performance no seu sistema com o uso adequado de orm em rails
count, length ou size ?
count
length
size
OO ou SQL?
Dê preferência ao uso de OO!
OO não pode sacrificar performance
ORM é um facilitador, conhecer SQL e banco de dados
ainda é importante
Não abra mão do poder do banco de dados
> SummaryOrder.all_summarized.explain
HashAggregate (cost=871.09..971.09 rows=10000 width=57)
Group Key: orders.id, customers.name
-> Hash Left Join (cost=349.70..796.09 rows=10000 width=57)
Hash Cond: (orders.customer_id = customers.id)
-> Hash Left Join (cost=319.00..639.24 rows=10000 width=33)
Hash Cond: (order_items.order_id = orders.id)
-> Seq Scan on order_items (cost=0.00..194.00 rows=10000 width=16)
-> Hash (cost=194.00..194.00 rows=10000 width=25)
-> Seq Scan on orders (cost=0.00..194.00 rows=10000 width=25)
-> Hash (cost=19.20..19.20 rows=920 width=40)
-> Seq Scan on customers (cost=0.00..19.20 rows=920 width=40)
Explain
Vimos resumidamente...
Includes
Joins Scopes
Mapeamentos Alternativos
New Relic Bullet
DB Query Matchers
Queries N+1
Count, Length, Size
Explain
Isso resolve todos
os problemas ?
provavelmente
não!
Talvez ainda seja
necessário...
● Reescrever
● Fragmentar
● Ou até usar outra
linguagem
Faça pelos
motivos adequados!
Verifique se o
problema de performance
não é mal uso de ORM
Obrigado !
Isaac Felisberto de Souza
isaacsouza@gmail.com
linkedin.com/in/isaacfsouza
Dúvidas ?

More Related Content

PPTX
Episode 4 - Introduction to SOQL in Salesforce
PDF
TDC2018SP | Trilha Ruby - Maior performance no seu sistema com o uso adequado...
PPTX
PPTX
Stored procedures
PPTX
Apex Testing and Best Practices
PPTX
Lab5 sub query
PDF
Database development coding standards
PPSX
Sql triggers
Episode 4 - Introduction to SOQL in Salesforce
TDC2018SP | Trilha Ruby - Maior performance no seu sistema com o uso adequado...
Stored procedures
Apex Testing and Best Practices
Lab5 sub query
Database development coding standards
Sql triggers

What's hot (10)

PPTX
Episode 6 - DML, Transaction and Error handling in Salesforce
PPT
Performance Instrumentation for PL/SQL: When, Why, How
PDF
WINDOWS ADMINISTRATION AND WORKING WITH OBJECTS : PowerShell ISE
PPTX
Java script advance-auroskills (2)
PPTX
Chapter 2 grouping,scalar and aggergate functions,joins inner join,outer join
PPTX
Java script – basic auroskills (2)
PPT
Testing Javascript with Jasmine
PPT
PPT
Beg sql
Episode 6 - DML, Transaction and Error handling in Salesforce
Performance Instrumentation for PL/SQL: When, Why, How
WINDOWS ADMINISTRATION AND WORKING WITH OBJECTS : PowerShell ISE
Java script advance-auroskills (2)
Chapter 2 grouping,scalar and aggergate functions,joins inner join,outer join
Java script – basic auroskills (2)
Testing Javascript with Jasmine
Beg sql
Ad

Similar to Maior performance no seu sistema com o uso adequado de orm em rails (20)

PDF
How to avoid hanging yourself with Rails
PPTX
Querying with Rails
KEY
Código Saudável => Programador Feliz - Rs on Rails 2010
PPTX
Active record(1)
PDF
Staying railsy - while scaling complexity or Ruby on Rails in Enterprise Soft...
ODP
Ruby on rails
DOCX
Ruby on Rails Developer - Allerin
KEY
Repensando o Desenvolvimento Web com Ruby on Rails
KEY
Active Record Query Interface (1), Season 2
PDF
Database Design Patterns
PPT
Doctrine 2 - Introduction
PDF
Ajax World2008 Eric Farrar
PPTX
Boosting the Performance of your Rails Apps
PDF
performance vamos dormir mais?
PDF
ActiveRecord Query Interface (2), Season 2
PPTX
TDC2016POA | Trilha Banco de Dados - RavenDB: um banco de dados NoSQL de segu...
PDF
Advanced O/R Mapping with Glorp
PDF
Intro to-rails-webperf
KEY
Onde mora a produtividade do Ruby on Rails?
PDF
Revenge of the ORMs
How to avoid hanging yourself with Rails
Querying with Rails
Código Saudável => Programador Feliz - Rs on Rails 2010
Active record(1)
Staying railsy - while scaling complexity or Ruby on Rails in Enterprise Soft...
Ruby on rails
Ruby on Rails Developer - Allerin
Repensando o Desenvolvimento Web com Ruby on Rails
Active Record Query Interface (1), Season 2
Database Design Patterns
Doctrine 2 - Introduction
Ajax World2008 Eric Farrar
Boosting the Performance of your Rails Apps
performance vamos dormir mais?
ActiveRecord Query Interface (2), Season 2
TDC2016POA | Trilha Banco de Dados - RavenDB: um banco de dados NoSQL de segu...
Advanced O/R Mapping with Glorp
Intro to-rails-webperf
Onde mora a produtividade do Ruby on Rails?
Revenge of the ORMs
Ad

More from Isaac de Souza (14)

PDF
Sua solução escala? Testes de Stress e APMs podem responder.
PDF
Seu código fonte é sustentável?
PDF
Compondo uma plataforma de software com microservices.
PDF
O que seus testes garantem, o funcionamento do código ou das funcionalidades ...
PDF
Esquenta TDC - Como DDD e principalmente Domain Model contribuem na construçã...
PDF
Compondo uma plataforma de software
PDF
A importância de DDD e o Domain Model na construção de APIs!
PDF
Desenhando a arquitetura do software!
PDF
Como DDD e principalmente Domain Model contribuem na construção de microservi...
PDF
Microservices em Python. Como estamos construindo a maior plataforma Agro do ...
PDF
A multiplicação dos devs!
PDF
Estamos trabalhando melhor com dependências e ambientes usando containers?
PDF
É hora de pensar em soluções portáveis na cloud!
PDF
Cloud computing, quais vantagens reais?
Sua solução escala? Testes de Stress e APMs podem responder.
Seu código fonte é sustentável?
Compondo uma plataforma de software com microservices.
O que seus testes garantem, o funcionamento do código ou das funcionalidades ...
Esquenta TDC - Como DDD e principalmente Domain Model contribuem na construçã...
Compondo uma plataforma de software
A importância de DDD e o Domain Model na construção de APIs!
Desenhando a arquitetura do software!
Como DDD e principalmente Domain Model contribuem na construção de microservi...
Microservices em Python. Como estamos construindo a maior plataforma Agro do ...
A multiplicação dos devs!
Estamos trabalhando melhor com dependências e ambientes usando containers?
É hora de pensar em soluções portáveis na cloud!
Cloud computing, quais vantagens reais?

Recently uploaded (20)

PDF
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
PDF
A novel scalable deep ensemble learning framework for big data classification...
PPTX
Tartificialntelligence_presentation.pptx
PDF
How ambidextrous entrepreneurial leaders react to the artificial intelligence...
PPTX
Final SEM Unit 1 for mit wpu at pune .pptx
PDF
Getting started with AI Agents and Multi-Agent Systems
PDF
A comparative study of natural language inference in Swahili using monolingua...
PPTX
Chapter 5: Probability Theory and Statistics
PPT
Module 1.ppt Iot fundamentals and Architecture
PDF
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
PPTX
O2C Customer Invoices to Receipt V15A.pptx
PDF
Hindi spoken digit analysis for native and non-native speakers
PDF
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
PPTX
Modernising the Digital Integration Hub
PDF
Enhancing emotion recognition model for a student engagement use case through...
PPTX
Web Crawler for Trend Tracking Gen Z Insights.pptx
PDF
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
PPTX
Benefits of Physical activity for teenagers.pptx
PDF
NewMind AI Weekly Chronicles – August ’25 Week III
PDF
sustainability-14-14877-v2.pddhzftheheeeee
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
A novel scalable deep ensemble learning framework for big data classification...
Tartificialntelligence_presentation.pptx
How ambidextrous entrepreneurial leaders react to the artificial intelligence...
Final SEM Unit 1 for mit wpu at pune .pptx
Getting started with AI Agents and Multi-Agent Systems
A comparative study of natural language inference in Swahili using monolingua...
Chapter 5: Probability Theory and Statistics
Module 1.ppt Iot fundamentals and Architecture
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
O2C Customer Invoices to Receipt V15A.pptx
Hindi spoken digit analysis for native and non-native speakers
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
Modernising the Digital Integration Hub
Enhancing emotion recognition model for a student engagement use case through...
Web Crawler for Trend Tracking Gen Z Insights.pptx
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
Benefits of Physical activity for teenagers.pptx
NewMind AI Weekly Chronicles – August ’25 Week III
sustainability-14-14877-v2.pddhzftheheeeee

Maior performance no seu sistema com o uso adequado de orm em rails