mongodb index性能測試

比較mongodb的集合在有索引和無索引的狀況下的insert,update(包括update 1個文檔和update全部文檔這2種狀況),find的性能差別。mongodb

測試方法,先在集合中插入1000條原始數據,以此爲基礎,重複執行2000次的insert,update,find來作性能比較,因爲find的速度比較快,實際中是採用10000條原始數據,重複執行100000來比較。測試的ruby代碼以下ruby

#!/usr/bin/env ruby
# 20140309, index_test.rb
###
# test index
###


require "rubygems"
require "mongo"
require "benchmark"

class MongoConnection
  def initialize(host, port)
    @mongoconn = Mongo::MongoClient.new(host, port)
    @db = @mongoconn.db("test")
  end

  def test()
    @coll = @db.collection("test")

    # insert test
    @coll.insert({"num"=>0})
    (1..1000).each { |i| @coll.insert({ num:i } ) }
    tm_start = Time.now.to_f
    Benchmark.bm do |t|
      t.report{ (1001..3000).each { |i| @coll.insert({ num:i } ) } }
    end
    # p @coll.find.to_a
    tm_used = Time.now.to_f - tm_start
    puts "Insert Time used(s): #{tm_used}"
    @coll.drop

    # update test
    @coll.insert({"num"=>0})
    (1..1000).each { |i| @coll.insert({ num:i } ) }
    tm_start = Time.now.to_f
    Benchmark.bm do |t|
      t.report{ (1001..3000).each { |i| @coll.update({ }, { "$set" => {"num"=>i} } ) } }
    end
    # p @coll.find.to_a
    tm_used = Time.now.to_f - tm_start
    puts "update_all Time used(s): #{tm_used}"
    @coll.drop

    # update test
    @coll.insert({"num"=>0})
    (1..1000).each { |i| @coll.insert({ num:i } ) }
    tm_start = Time.now.to_f
    Benchmark.bm do |t|
      t.report{ (1001..3000).each { |i| @coll.update({ num:300 }, { "$set" => {"num"=>i} } ) } }
    end
    # p @coll.find.to_a
    tm_used = Time.now.to_f - tm_start
    puts "update Time used(s): #{tm_used}"
    @coll.drop

    # find test
    @coll.insert({"num"=>0})
    (1..10000).each { |i| @coll.insert({ num:i } ) }
    tm_start = Time.now.to_f
    Benchmark.bm do |t|
      t.report{ (1..100000).each { |i| x = @coll.find({ num:5000 } ) } }
    end
    # p @coll.find.to_a
    tm_used = Time.now.to_f - tm_start
    puts "find Time used(s): #{tm_used}"
    @coll.drop

  end

  def test_index()
    @coll = @db.collection("test")

    # insert test
    @coll.insert({"num"=>0})
    (1..1000).each { |i| @coll.insert({ num:i } ) }
    @coll.create_index( :num=>Mongo::ASCENDING )
    tm_start = Time.now.to_f
    Benchmark.bm do |t|
      t.report{ (1001..3000).each { |i| @coll.insert({ num:i } ) } }
    end
    # p @coll.find.to_a
    tm_used = Time.now.to_f - tm_start
    puts "insert Time used(s): #{tm_used}"
    @coll.drop

    # update test
    @coll.insert({"num"=>0})
    (1..1000).each { |i| @coll.insert({ num:i } ) }
    @coll.create_index( :num=>Mongo::ASCENDING )
    tm_start = Time.now.to_f
    Benchmark.bm do |t|
      t.report{ (1001..3000).each { |i| @coll.update({ }, { "$set" => {"num"=>i} } ) } }
    end
    # p @coll.find.to_a
    tm_used = Time.now.to_f - tm_start
    puts "update_all Time used(s): #{tm_used}"
    @coll.drop

    # update test
    @coll.insert({"num"=>0})
    (1..1000).each { |i| @coll.insert({ num:i } ) }
    @coll.create_index( :num=>Mongo::ASCENDING )
    tm_start = Time.now.to_f
    Benchmark.bm do |t|
      t.report{ (1001..3000).each { |i| @coll.update({ num:300 }, { "$set" => {"num"=>i} } ) } }
    end
    # p @coll.find.to_a
    tm_used = Time.now.to_f - tm_start
    puts "update Time used(s): #{tm_used}"
    @coll.drop

    # find test
    @coll.insert({"num"=>0})
    (1..10000).each { |i| @coll.insert({ num:i } ) }
    @coll.create_index( :num=>Mongo::ASCENDING )
    tm_start = Time.now.to_f
    Benchmark.bm do |t|
      t.report{ (1..100000).each { |i| x = @coll.find({ num:5000 } ) } }
    end
    # p @coll.find.to_a
    tm_used = Time.now.to_f - tm_start
    puts "find Time used(s): #{tm_used}"
    @coll.drop

  end

end

mongo_conn = MongoConnection.new("localhost", 27017)

puts "======TEST WITHOUT INDEX========================"
mongo_conn.test()
puts "======TEST WITH INDEX==========================="
mongo_conn.test_index()

測試結果以下性能

======TEST WITHOUT INDEX========================
       user     system      total        real
   1.000000   0.080000   1.080000 (  1.401279)
Insert Time used(s): 1.4016945362091064
       user     system      total        real
   1.050000   0.090000   1.140000 (  1.442167)
update_all Time used(s): 1.442460298538208
       user     system      total        real
   1.250000   0.180000   1.430000 (  4.492881)
update Time used(s): 4.493251085281372
       user     system      total        real
   2.740000   0.000000   2.740000 (  2.743044)
find Time used(s): 2.7432751655578613
======TEST WITH INDEX===========================
       user     system      total        real
   0.980000   0.110000   1.090000 (  1.461577)
insert Time used(s): 1.4617598056793213
       user     system      total        real
   1.020000   0.130000   1.150000 (  1.601074)
update_all Time used(s): 1.6013922691345215
       user     system      total        real
   1.140000   0.140000   1.280000 (  1.784649)
update Time used(s): 1.7848689556121826
       user     system      total        real
   2.710000   0.000000   2.710000 (  2.699411)
find Time used(s): 2.6996209621429443

對於以上結果,在有index的時候,insert單條文檔,update全部文檔這2種狀況比沒有index的時候略差一點,從上面的數據來看,大約是差5%~10%;update單個文檔的性能,有index的時候,要遠好於沒有index的時候,時間上大約要少60%;使人出乎意料的是find的性能,彷佛差別並不明顯,有索引的時候僅僅略優於沒有索引的狀況,差別小於5%。測試

相關文章
相關標籤/搜索