比較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%。測試