MongoDB������������\¹\­���¼\���\���\¹������DB��������¡�\«\���\�������·��������������������������������������������Ï�����¾���¹���������»��������Ï�����������²��������쏢���������я�����������»�ߏ����Ï����я��������¹���̏�¡��ӏ��½�����Ï�����������\������¼\��ď�����\���\���\·\������������·��������¡�JSON ·���¼�돢���� MySQL �����������򏪤������¹���������Ð�����������������������������폢¡ߏ����������������á돪؏��«�����ҏ����������ď����������������ď�����������¡��½������¾���¹���������������\Ð\���\��폢�¼\���\���\¹������³��я����ҏ��·�����������Ώ��������·�����ď�¡�

�񡯏�돪�½��������� MySQL ���������·������ innodb ���������·���«���¾²������·���������������������«�����������ď����ď�������¡�myisam ������·���²���������������������������������������µ­���·���������·�����ď�¡�(2010/04/25������µ­)

\���\���\���\������¼\����������­������½��������


»����·�����ġ������­���������·��������������¡�MySQL 5.1.45, MongoDB 1.2.4 ���������¹��¡�MySQL�����Ï��������³�����я�����������������¡�

mysql> desc blogs;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255) | YES  |     | NULL    |                |
| category   | varchar(255) | YES  |     | NULL    |                |
| created_at | datetime     | YES  |     | NULL    |                |
| updated_at | datetime     | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

mysql> desc articles;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| title      | varchar(255) | YES  |     | NULL    |                |
| blog_id    | int(11)      | YES  |     | NULL    |                |
| other      | text         | YES  |     | NULL    |                |
| created_at | datetime     | YES  |     | NULL    |                |
| updated_at | datetime     | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

# blog.rb
class Blog < ActiveRecord::Base
  has_many :articles
end

# article.rb
class Article < ActiveRecord::Base
end


MongoDB�����Ï��������³�����я�����������������¡�

# config/environment.rb
require 'mongo_mapper'
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
MongoMapper.database = 'db_name'

# blog_mongo.rb
class BlogMongo
  include MongoMapper::Document

  key :name, String
  key :category, String

  many :article_mongos
end

# article_mongo.rb
class ArticleMongo
  include MongoMapper::EmbeddedDocument

  key :title, String
end

��������������������������������\���\���\���\������������¹���̏�¡��½���������¾������\���\���\�돢����µ­»��ӏ����¡����·���������¹�����𡯏��������¹��¡�MySQL �����Ï����������� blogs \������¼\���\��������� articles \������¼\���\���������¹�����𡯏�������¡�articles \������¼\���\��������� other \«\���\�����������¡�\���\���\·\��������� JSON ·���¼�돢�������·�����ď��������������ҏ����򏪤������¹���������������·���������¹��¡�MongoDB �����Ï����������� blog_mongos \³\���\���\·\���\��я����������� article_mongos \³\���\���\·\���\��я����ҏ�����������¹��Џ����я���������������������»������������������¹��¡�article_mongos \³\���\���\·\���\��я�����������\«\���\������� MySQL �����Ï����� other \«\���\������������Ð�ޏ�Џ��·���������������������¹��¡�

\���\���\���\������¼\���������»���������������\³���¼\����������돪�²¼���������������쏢������¡�

class BenchController < ApplicationController
  require 'json'
  require 'benchmark'

  def insert
    Benchmark.bm do |x|
      x.report('mysql') {
        1.upto(20000) do |num|
          @blog = Blog.new(
            :name => "name_#{num}",
            :category => "category_#{num}"
          )
          @blog.save!
          1.upto(10) do |num2|
            data = {
              :hoge => "hoge_#{num2}", # ����돪���쏢����\«\���\���
              :fuga => "fuga_#{num2}", # ����돪���쏢����\«\���\���
              :foo => "foo_#{num2}" # ����돪���쏢����\«\���\���
            }
            hash = {
              :title => "title_#{num2}",
              :blog_id => @blog.id,
              :other => data.to_json # hash -> JSON
            }
            @article = Article.new(hash)
            @article.save!
          end
        end
      }
      x.report('mongodb') {
        1.upto(20000) do |num|
          @blog_mongo = BlogMongo.new(
            :name => "name_#{num}",
            :category => "category_#{num}"
          )
          1.upto(10) do |num2|
            @blog_mongo.article_mongos << ArticleMongo.new(
              :title => "title_#{num2}",
              :hoge => "hoge_#{num2}", # ����돪���쏢����\«\���\���
              :fuga => "fuga_#{num2}", # ����돪���쏢����\«\���\���
              :foo => "foo_#{num2}" # ����돪���쏢����\«\���\���
            )
          end
          @blog_mongo.save!
        end
      }
    end

    render :text => "finish"
  end

  def select
    Benchmark.bm do |x|
      x.report('mysql') {
        1.upto(1000) do |num|
          name = "name_#{1 + rand(20000)}"
          Blog.uncached {
            @blog = Blog.find(
              :first,
              :conditions => ['name = ?', name]
            )
          }
        end
      }
      x.report('mongodb') {
        1.upto(1000) do |num|
          name = "name_#{1 + rand(20000)}"
          @blog_mongo = BlogMongo.first(:name => name)
        end
      }
    end

    render :text => "finish"
  end

  def select_join
    Benchmark.bm do |x|
      x.report('mysql') {
        1.upto(1000) do |num|
          title = "title_#{1 + rand(10)}"
          name = "name_#{1 + rand(20000)}"
          Blog.uncached {
            @blog = Blog.find(
              :first,
              :joins => :articles,
              :conditions => ['name = ? AND title = ?', name, title]
            )
            @blog.articles.each do |article|
              JSON.parse(article.other)["hoge"] # JSON -> hash
            end
          }
        end
      }
      x.report('mongodb') {
        1.upto(1000) do |num|
          title = "title_#{1 + rand(10)}"
          name = "name_#{1 + rand(20000)}"
          @blog_mongo = BlogMongo.first(:name => name, 'article_mongos.title' => title)
          @blog_mongo.article_mongos.each do |article_mongo|
            article_mongo.hoge
          end
        end
      }
    end

    render :text => "finish"
  end
end

insert


�����������돢���� insert ������\���\���\��폢�¼\���\���\¹�����ҏ��«�����������Ώ��������¹ (def insert)��¡�total ������ real �����¡돫����������̏��������������������«���������������»�����я��̏�¡�¡���¼�����돪�����½��������򏪤�����㏢���� total ���������ޏ�������¡񏪢��䏪�³������\Ð\���\���\������㏢���ҡ���������������ď������� real ??����insert ������������������������������ MongoDB ������������6�����䏢���叢���������������������������Ï��������¹��¡�

         user        system     total       real
innodb   533.340000  29.960000  563.300000  (705.781767)
myisam   507.690000  25.520000  533.210000  (595.685193)
mongodb  118.620000   3.010000  121.630000  (123.262020)

select


¼������� select ���������¹��¡�돪�½��������������½��������� select ������»����·�����������Ώ��������·������������ (def select)��¡��³������¾���¹��������������叢���䏩��ޏ�����������������������������·���²������������������������������·�����ď�¡򏪢�������������½��������� select ���������������� MySQL ������������½½����̏����������������������������������Ï��³���������������·�����������Ï��«��¡�

         user      system    total     real
innodb   0.650000  0.060000  0.710000  (8.550134)
myisam   0.630000  0.050000  0.680000  (5.288588)
mongodb  1.450000  0.070000  1.520000  (7.131137)

JOIN ������ JSON.parse �����ҡ���������� select


������������������������¾������·¼��������폪���쏢���� select ������»����·�����������Ώ��������·������������ (select_join)��¡�JOIN �����ҏ��·��������¡��µ������������ JSON ������\���\���\·\��������������С�¹���·���������������������¹��¡��½���������½����������²��я��������������ď��«�����������ď������������³�����Ï�����������¾���·���������������\���\���\��폢�¼\���\���\¹���������·�����ď��������������쏢�³������¾���¹�����������µ�����򏪩��쏢���� MongoDB �����������̏�����������������������������·���²������������������������������·�����ď���

         user      system    total     real
innodb   2.500000  0.390000  2.890000  (333.170427)
myisam   2.380000  0.260000  2.640000  (192.624045)
mongodb  2.630000  0.120000  2.750000  ( 28.786100)

�����ď��������³������������������ index �����ҏ��\���������������������������������������������ӏ��³��������������𡯏��Ð�����ӏ��³������·���²������«���������·���������������»�����я�¡����������� index �����ҏ��\�����������������Ώ����������������������Ï��������·�����������Ï��«�����돪�²¼���������������Ï����� index �����ҏ��\�����������������Ώ��������·�����������Ï�¡�

# mysql
mysql> ALTER TABLE articles add index blog_id_and_title(blog_id, title);
Query OK, 200000 rows affected (5.32 sec)
Records: 200000  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE blogs add index name(name);
Query OK, 20000 rows affected (0.81 sec)
Records: 20000 Duplicates: 0  Warnings: 0

# mongodb
> db.blog_mongos.ensureIndex({"name":1, "article_mongos.title":1})
Sat Apr 24 23:24:25 building new index on { name: 1.0, article_mongos.title: 1.0 } for verification.blog_mongos...
Sat Apr 24 23:24:25 Buildindex verification.blog_mongos idxNo:1 { ns: "verification.blog_mongos", key: { name: 1.0, article_mongos.title: 1.0 }, name: "name_1_article_mongos.title_1" }

Sat Apr 24 23:24:27 done for 20000 records 2.087secs
Sat Apr 24 23:24:25 insert verification.system.indexes 2087ms

·���²������������³���������������Ï��������������������������·�����ď�¡�

index �����ҏ��\�����������ď����������� JOIN �����ҡ���������� select


         user      system    total     real
innodb   1.880000  0.110000  1.990000  (2.838279)
myisam   1.770000  0.080000  1.850000  (2.661035)
mongodb  2.280000  0.080000  2.360000  (2.561867)

�����������������Џ����� index ��������������������������¹��������¡�����������������������¹���������²½���µ����������������ޏ�����������������������������\���\���\��폢�¼\���\���\¹���������������������������·�����ď��¼��¡����ď����� index �����ҏ��\���������������·�����������Ï�����µ�����������������������������\������¼\��ď����������Џ�����¹¹���·»��Џ�����\¹\��ԏ��¼\������̏����㏢�������������������������·�����������Ï��³���������������¹��¡��³������¾��؏����ӏ�����²��Џ�����������\������¼\��ď����ҏ����������Џ��¹�����������������������Ï��������·�����������Ï��«����

         user        system     total       real
innodb   535.240000  27.940000  563.180000  (701.159550)
myisam   505.380000  23.260000  528.640000  (606.803967)
mongodb  119.430000   3.030000  122.460000  (127.414991)

����������������¡񏪡�����³�����Џ��������������������������������¹��������¡��³���������̏����㏢���� index �����������������������Ï��������������³���������������������������������³�������������������������·�����������Ï��«��¡��½���������؏�����²��ҏ��­���������������������������������������������«���������������»�����я�¡�¡������������ޏ��������������������������������돢¡�

������������������


�����������������Ï��������ޏ�������������������������������������¡�

����insert ������ MongoDB�����������̏�����������
����index �����ҏ��\������������������¾���¹�����¡�select ������ MongoDB�����������̡�µ�����򏪩��쏢����������������
����index �����ҏ��\���������Ð����ޏ�����������������������������\���\���\��폢�¼\���\���\¹����½Ð������
���Ï����ď��������·��¡�index �����ҏ��\������������\������¼\��ď��������������Џ�����¹¹���·������\���\���\��폢�¼\���\���\¹���̏��������������������������������돪؏��̏���̏����
����MongoDB ������������������¹��Џ����Ώ��­���½���������ޏ�������������������������¡�½��Џ��­¹��Џ����Ώ��­���½������¹���������
����MongoDB ������ index �����ҏ��\���������������������������������½���³���½���³�������­���½����½Ð������

�����������������������ď��������³���������������·�����������Ï��«��¡�½��Џ��­¹��Џ����Ώ��­���½������¹��������������������������������Ï������̡���ҏ��·���������������¹��������¡�½��Џ��­¹��Џ����Ώ��������ď�����½�������������³��������ӏ��·���������������������½�����Ï��������¹��¡�µ��؏������������я�����������½��Џ��­¹��Џ����Ώ��­���½������µ���������������������������������½������������������� MySQL ������ JSON �����򏪤�����¡������������������������«��������¡�
³\\\\¼ҏ\\\\¼\²