Skip to content

Instantly share code, notes, and snippets.

@ifyouseewendy
Created May 8, 2014 11:43
Show Gist options
  • Save ifyouseewendy/0069c0498274d2dd5a6d to your computer and use it in GitHub Desktop.
Save ifyouseewendy/0069c0498274d2dd5a6d to your computer and use it in GitHub Desktop.
by latest two versions, '4.0.0.beta1' behaves much better than '3.1.6'
#!/usr/bin/env ruby
# encoding: utf-8
# ======================================================
# <N+1 problem>
#
# Post.all.each do |p|
# puts p.category.name
# end
#
# select * from POSTS;
#
# select * from CATEGORYS where POST_ID=1;
# select * from CATEGORYS where POST_ID=2;
# select * from CATEGORYS where POST_ID=3;
# select * from CATEGORYS where POST_ID=4;
#
# --- solution ---
#
# Post.all.includes(:category).each do |p|
# puts p.category.name
# end
#
# select * from POSTS;
#
# select CATEGORY.* from CATEGORY
# where CATEGORY.POST_ID IN (1,2,3,4)
#
# ======================================================
require 'rubygems'
require 'faker'
# ====================================
# comment to switch mongoid version
# result in different performance
#
gem 'mongoid', "3.1.6"
# gem 'mongoid', "4.0.0.beta1"
# ====================================
require 'mongoid'
require 'benchmark'
# This call creates a connection to our database.
Mongoid::Config.connect_to('test')
# Mongoid::Config.identity_map_enabled = true
# First, set up our database...
class Category
include Mongoid::Document
has_many :items
field :name
end
class Item
include Mongoid::Document
belongs_to :category
end
Category.create(:name=>"Sara Campbell Stuff")
Category.create(:name=>"Jake Moran Possessions")
Category.create(:name=>"Josh Items")
number_of_categories = Category.count
puts "Loading data..."
item_count = Item.count
item_table_size = 10000
if item_count < item_table_size
(item_table_size - item_count).times do
Item.create!(:name=>Faker.name,
:category_id=>(1+rand(number_of_categories.to_i)))
end
end
puts "Running tests..."
Benchmark.bm do |x|
[100,1000,10000].each do |size|
x.report "size:#{size}, with n+1 problem" do
@items=Item.all.limit(size)
@items.each do |i|
i.category
end
end
x.report "size:#{size}, with :include" do
@items=Item.all.includes(:category).limit(size)
@items.each do |i|
i.category
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment