我的家園

          我的家園

          一直好奇于MongoDB的讀寫速度以及它的特有的NoSQL查詢機制。有幸作了一次Sybase ASA(SQLAnywhere12)和MongoDB寫入數據行的速度的比較。

          這對于大規模Web訪問來說,非常重要。
          比較基準:

          寫入100000行,每行三列,id(整數), name varchar(32),  col_blob或clob,8K左右長度。比較最終的寫入時間。
          1. ASA12:

          dbinit.exe bench.db
          dbeng12.exe bench.db
          代碼如下:

          package com.sql9;

          import java.sql.*;
          import java.util.Properties;


          public class Bench4SQLAnywhere
          {
              // prepare about 100000 rows of data
              // (id, name, col_clob)
              // e.g. (1, 'wang', 'abcdef12345555555555555555555555555555555555555555555....')
              // the col_blob should be 8K or longer.
              // dsn: benchASA
              
              public static final String DSN = "bench_ASA";
              
              public static final String url = "jdbc:sqlanywhere:UserID=dba;Password=sql;Server=bench;DBN=bench";
              
              public static void testWrite()
              {
                  Connection conn = null;
                  
                  System.out.println("begin time: " + new Timestamp(new java.util.Date().getTime()));
                  // System.setProperty("java.library.path",  "v:/target/ASA120/Bin32");
                  
                  
                  try
                  {
                      Properties props = new Properties();
                      props.put("DYNAMIC_PREPARE", true);
                      conn = DriverManager.getConnection("jdbc:sqlanywhere:DSN=" + DSN + ";uid=dba;pwd=sql", props);
                      // conn = DriverManager.getConnection(url, props);
                      
                      Statement stmt = conn.createStatement();
                      stmt.executeUpdate("create table t(id int primary key, name varchar(32) null, col_blob long varchar null)");
                      stmt.close();
                      stmt = null;
                      
                      PreparedStatement pstmt = conn.prepareStatement("insert into t values(?, ?, ?)");
                      StringBuilder sb = new StringBuilder(8000);
                      for (int i=0; i<800; i++)
                      {
                          sb.append("abcde12345");
                      }
                      
                      for (int i=0; i<100000; i++)
                      {
                          pstmt.setInt(1, i+1);
                          pstmt.setString(2, "wang " + i);
                          pstmt.setString(3, sb.toString());
                          pstmt.executeUpdate();
                          if ((i+1) % 1000 == 0)
                          {
                              conn.commit();
                          }
                      }
                      conn.commit();
                      
                      pstmt.close();
                  }
                  catch (Exception ex)
                  {
                      ex.printStackTrace();
                  }
                  finally
                  {
                      // if conn not null, just drop the table ????
                  }
                  
                  System.out.println("end time: " + new Timestamp(new java.util.Date().getTime()));
                  
                  try
                  {
                      if (conn != null)
                      {
                          Statement stmt = conn.createStatement();
                          stmt.executeUpdate("drop table t");
                          stmt.close();
                      }
                  }
                  catch (Exception ex)
                  {
                      ex.printStackTrace();
                  }
                  finally
                  {
                      if (conn != null)
                      {
                          try
                          {
                              conn.close();
                          }
                          catch (Exception ex2) {}
                      }
                  }
                  
              }
              
              /**
               * @param args
               */
              public static void main(String[] args)
              {
                  // TODO Auto-generated method stub
                  testWrite();
              }

              
              
              /**
               * result
               *  begin time: 2012-04-12 17:44:22.292
                  end time: 2012-04-12 17:55:16.971
               */
          }

          我們可以看到最終結果: begin time: 2012-04-12 17:44:22.292
                  end time: 2012-04-12 17:55:16.971, 大概花了11分鐘。是夠慢的
          運行時需要指定-Djava.library.path=<asa12>/bin32目錄。

          2. MongoDB:
          啟動:mongod.exe --dbpath E:\xionghe\MongoDB\mongodb\data

          客戶端簡單命令:

          db.testCollection.count()
          代碼如下:

          package com.sql9;

          import java.net.UnknownHostException;
          import java.sql.Timestamp;
          import java.util.HashMap;

          import com.mongodb.Mongo;
          import com.mongodb.DB;
          import com.mongodb.DBCollection;
          import com.mongodb.BasicDBObject;
          import com.mongodb.DBObject;
          import com.mongodb.DBCursor;
          import com.mongodb.MongoException;

           

          public class Bench4MongoDB
          {

              
              public static void testWrite() throws UnknownHostException, MongoException
              {
                  Mongo m = new Mongo();
               // or
               // Mongo m = new Mongo( "localhost" );
               // or
               // Mongo m = new Mongo( "localhost" , 27017 );

                  System.out.println("begin time: " + new Timestamp(new java.util.Date().getTime()));
                  
                  DB db = m.getDB( "test" );
                  
                  StringBuilder sb = new StringBuilder(8000);
                  for (int i=0; i<800; i++)
                  {
                      sb.append("abcde12345");
                  }
                  
                  // on row looks like

                  DBCollection col = db.getCollection("testCollection");
                  for (int i=0; i<100000; i++)
                  {
          //            pstmt.setInt(1, i+1);
          //            pstmt.setString(2, "wang " + i);
          //            pstmt.setString(3, sb.toString());
          //            pstmt.executeUpdate();
          //            if ((i+1) % 1000 == 0)
          //            {
          //                conn.commit();
          //            }
                      
                      BasicDBObject doc = new BasicDBObject();
                      doc.put("id", i);
                      doc.put("name", "wang " + i);
                      doc.put("col_blob", sb.toString());
                      // col.insert(doc);
                      col.save(doc);
                  }
                  System.out.println("end time: " + new Timestamp(new java.util.Date().getTime()));
                  
                  // finally remove the col1 from the mongoDB.
                  // col.remove(new BasicDBObject(new HashMap()));
              }
              
              /**
               * @param args
               */
              public static void main(String[] args)
              {
                  // TODO Auto-generated method stub
                  try
                  {
                      testWrite();
                  }
                  catch (UnknownHostException e)
                  {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
                  catch (MongoException e)
                  {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
              
              /**
          begin time: 2012-04-12 18:11:18.99
          end time: 2012-04-12 18:11:44.412
           
               */

          }

          看看所花時間:
          begin time: 2012-04-12 18:11:18.99
          end time: 2012-04-12 18:11:44.412
          只花了: 26秒左右。

          我只能說差距太明顯了。。。。。。。
          再看看生成的文件大小:
          bench.db:  814,900KB, .log: 819328KB.
          mongodb的testdb: test.* (test.0,   ... test.5)共6個文件1,073,479,685B也就1G左右。

          分析:
          ASA之所以慢如此之多,一是它基于關系表,有一個BLOB/CLOB字段要跨頁存儲,同時它要維護主鍵的索引。MongoDB則沒有維護索引。可能對testCollection創建一個索引,再進行比較更合理一些,但我有理由相信,即算加上索引,MongoDB也比ASA要快很多。

          看來,MongoDB適用于互聯網所言非虛。
          不過,我再看了下MongoDB的license:

           是一個開放源碼項目,其數據庫基于 GNU AGPL (Affero General Public License) version 3.0 的許可。此許可是 GNU GPL 的一個修正版,它彌補了版權限制不適用于軟件使用而僅適用軟件分發的漏洞。這對于在云中存儲而不經常安裝在客戶端設備上的軟件當然是重要的。使用常規 GPL ,您會感覺到實際上無法進行分發,因此潛在地規避了許可條款。

          AGPL 只適用于它自己的數據庫應用程序,不適用于 MongoDB 的其他組成部分。允許開發人員從各種編程語言連接 MongoDB 的官方驅動程序在 Apache License Version 2.0 許可下分發。 MongoDB 文檔的使用基于 Creative Commons 許可。

          這是否意味著,如果我要開發一款基于Cloud的大型互聯網應用,可以直接使用MongoDB和自己的產品集成,而沒有任何法律風險?
          有熟悉此道的朋友,請告訴我。。。


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 谢通门县| 黄大仙区| 色达县| 临安市| 嘉荫县| 儋州市| 响水县| 陇西县| 汾阳市| 资溪县| 柳州市| 奉节县| 资中县| 镇雄县| 普格县| 彭山县| 婺源县| 神农架林区| 子洲县| 库车县| 阜康市| 英吉沙县| 马龙县| 金溪县| 开鲁县| 崇州市| 丹东市| 华蓥市| 富阳市| 涪陵区| 绥中县| 双桥区| 疏附县| 宣城市| 天峨县| 水富县| 云南省| 普兰县| 白沙| 白朗县| 泾川县|