<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    分享下自己用sql語句批量插入測試數據(企業級 百萬數據級別)的方法

    由于公司準備用discuz建立企業級的論壇,所以需要進行百萬級數據的測試。
    搜索了很久沒有看到相關的批量插入數據的資料,后來找到一個批量插入帖子的插件,但導入的txt文件超過2350條記錄就插入不了。最后只好硬著頭皮分析插入帖子的相關sql語句--直接插入到cdb_posts表前臺不會顯示的。
    最后簡化為只有標題和內容的帖子需要在兩個表插入記錄,最后更新cdb_foums對應的一條數據即可。
    由于是本人主要是開發java的對php不熟悉,所以測試代碼是用java寫的,但懂php的人根據我的思路用php也應該很容易搞定了。
    最后分享下代碼:(用jdbc連接數據庫的,需要在java web項目下的lib目錄下導入mysq的jar包)

    =====================================
    DBManager.java
    =====================================
    package com.test.utc;
    import java.sql.*;

    public class DBManager {
    //用戶名
    private String user = "";
    //密碼
    private String password = "";
    //主機
    private String host = "";
    //數據庫名字
    private String database = "";

    /*
         private String url="jdbc:mysql://"+host+"/"+"useUnicode=true&characterEncoding=GB2312";
       */
    private String url ="";
    private Connection con = null;

    Statement stmt;
    /**
       * 根據主機、數據庫名稱、數據庫用戶名、數據庫用戶密碼取得連接。
       * @param host String
       * @param database String
       * @param user String
       * @param password String
       */
    public DBManager(String host, String database, String user, String password) {

        this.host = host;
        this.database = database;
        this.user = user;
    this.password = password;
    //顯示中文
        this.url = "jdbc:mysql://" + host + "/" + database +
            "?useUnicode=true&characterEncoding=GB2312";

        try {
          Class.forName("org.gjt.mm.mysql.Driver");
        }
        catch (ClassNotFoundException e) {
          System.err.println("class not found:" + e.getMessage());
        }

        try {
          con = DriverManager.getConnection(this.url, this.user, this.password);
    //連接類型為ResultSet.TYPE_SCROLL_INSENSITIVE,                                 ResultSet.CONCUR_READ_ONLY
          stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
                                     ResultSet.CONCUR_READ_ONLY);
        }
        catch (SQLException a) {
          System.err.println("sql exception:" + a.getMessage());
        }
    }
    /**
    * 返回取得的連接
    */
    public Connection getCon() {
        return con;
    }
    /**
    * 執行一條簡單的查詢語句
    * 返回取得的結果集
    */
    public ResultSet executeQuery(String sql) {
        ResultSet rs = null;
        try {
          rs = stmt.executeQuery(sql);
        }
        catch (SQLException e) {
          e.printStackTrace();
        }
        return rs;
    }
    /**
    * 執行一條簡單的更新語句
    * 執行成功則返回true
    */
    public boolean executeUpdate(String sql) {
        boolean v = false;
        try {
          v = stmt.executeUpdate(sql) > 0 ? true : false;
        }
        catch (SQLException e) {
          e.printStackTrace();
        }
        finally {
          return v;
        }
    }
    }
    ======================
    一次同時插入兩個表,for循環后更新數據。
    為了方便同時加入了納米級別的時間差,并且把詳細信息輸出到指定文件中。
    轉換16進制的單獨測試沒有問題,但轉換后作為sql語句插入總是提示過大或者是中文的轉換后不能識別,比較郁悶。不過這個不是很重要的問題。
    插入的文件InsertIntoSQL .java如下:
    ======================
    package com.test.utc;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import com.test.utc.DBManager;
    public class InsertIntoSQL
    {
    public final static String path = "D:/ComsenzEXP/wwwroot/discuz/attachments/testLog.txt";

    public static void main (String[] agrs)
    {
       //System.out.println(toHexString("測試"));
       //System.out.println(toStringHex("0x74657374"));
       insertData(300000,4,100000,"test","test");

    }


    /*
    * @deprecated 插入數據
    * @param startNumber
    * @param endNumber
    * @param fourmid
    * @param postsNumber
    * @param todayposts
    */
    public static void insertData(long insertNumber,int fourmid,long todayposts,String title,String content)
    {
       String message = "插入:" + insertNumber + "條記錄";
       System.out.println(message);
       appendMethod(path,message);

       long startTime = System.nanoTime();
       message = "insertData startTime:" + startTime;
       System.out.println(message);
       appendMethod(path,message);
      
      
        DBManager dbm = new DBManager("localhost:6033", "discuz", "discuz", "discuzexp");
       String sql = "";
       String pid = getLastRowByColumnValue(dbm,"cdb_posts","pid");
       long startNumber = Long.parseLong(pid) + 1;
       long endNumber = startNumber + insertNumber;
       long i = 1;
       //content = toHexString(content);
       //0x6d4b8bd551855bb9
       //0x6d4b8bd5
       //String insertTitle = title;
       for(i = startNumber; i < endNumber; i++)
       {
        //insertTitle = insertTitle + i;
        //insertTitle = toHexString(insertTitle + i);
      
        sql = "INSERT INTO cdb_posts VALUES ('" + i + "','" + fourmid + "','" + i + "','1',0x61646d696e,'1',0x74657374,'1221120302',0x74657374,0x3139322e3136382e302e3335,'0','0','0','0','-1','-1','0','0','0','0','0')";
        dbm.executeUpdate(sql);
        sql = "INSERT INTO cdb_threads VALUES ('" + i + "','" + fourmid + "','0','0','0','0',0x61646d696e,'1',0x74657374,'1221120302','1221120302',0x61646d696e,'1','0','0','0','0','0','0','0','0','0','0','0','0','0','0')";  
        dbm.executeUpdate(sql);
      
        /*
        sql = "INSERT INTO cdb_posts VALUES ('" + i + "','" + fourmid + "','" + i + "','1',0x61646d696e,'1','" + insertTitle + "','1221120302','" + content + "',0x3139322e3136382e302e3335,'0','0','0','0','-1','-1','0','0','0','0','0')";
        dbm.executeUpdate(sql);
        sql = "INSERT INTO cdb_threads VALUES ('" + i + "','" + fourmid + "','0','0','0','0',0x61646d696e,'1','" + insertTitle + "','1221120302','1221120302',0x61646d696e,'1','0','0','0','0','0','0','0','0','0','0','0','0','0','0')";  
        dbm.executeUpdate(sql);
        */
       }
       todayposts = endNumber - 499999;
       sql = "UPDATE cdb_forums SET lastpost='0x74657374', threads=" + endNumber + ", posts=" + endNumber + ", todayposts=" + todayposts + " WHERE fid=" + fourmid;
       dbm.executeUpdate(sql);

       message = "insertData endTime:" + System.nanoTime();
       System.out.println(message);
       appendMethod(path,message);

       long estimatedTime = System.nanoTime() - startTime;
       message = "相差(用時):" + estimatedTime + "納秒," + estimatedTime/1000000000 + "秒\r\n\r\n";//1秒=10億納秒
       System.out.println(message);
       appendMethod(path,message);
    }

    /*
    * @deprecated 獲取最后一行某列的值
    * @param table
    * @param column
    */
    public static String getLastRowByColumnValue(DBManager dbm,String table,String column)
    {
       String sql = "";
       sql = "select " + column + " from " + table + " order by " + column + " desc limit 1";
       ResultSet rs = dbm.executeQuery(sql);
       String str = "";
       try {
        while( rs.next())
        {
         str = rs.getString(column);
        }
       } catch (SQLException e) {

        e.printStackTrace();
       }
       return str;
    }

    //轉化字符串為十六進制編碼
    public static String toHexString(String s)  
    {  
       String str="";  
       for (int i=0;i<s.length();i++)  
       {  
        int ch = (int)s.charAt(i);  
        String s4 = Integer.toHexString(ch);  
        str = str + s4;
       }  
       return "0x" + str;  
    }

    /**
        * B方法追加文件:使用FileWriter
        * @param fileName
        * @param content
        */
    public static void appendMethod(String fileName, String content){
        try {
         //打開一個寫文件器,構造函數中的第二個參數true表示以追加形式寫文件
         FileWriter writer = new FileWriter(fileName, true);
         writer.write(content + "\r\n");
         writer.close();
        } catch (IOException e) {
         e.printStackTrace();
        }
    }

    }
    =========================
    測試結果
    =========================
    插入:1條記錄
    insertData startTime:996017275659
    insertData endTime:996570971450
    相差:555546585納秒,0秒

    插入:10條記錄
    insertData startTime:1005210041220
    insertData endTime:1005774437812
    相差:566248503納秒,0秒

    插入:100條記錄
    insertData startTime:1014529111102
    insertData endTime:1015376139146
    相差:848823244納秒,0秒

    插入:1000條記錄
    insertData startTime:1024027419406
    insertData endTime:1027460295093
    相差:3434544614納秒,3秒


    插入:10000條記錄
    insertData startTime:1098779316644
    insertData endTime:1116864493392
    相差:18086540050納秒,18秒

    插入:20000條記錄
    insertData startTime:1172427124676
    insertData endTime:1207721237196
    相差:35295511580納秒,35秒

    插入:30000條記錄
    insertData startTime:1221623540422
    insertData endTime:1273396534755
    相差:51774426358納秒,51秒

    插入:40000條記錄
    insertData startTime:1304022174326
    insertData endTime:1373074817609
    相差:69054081175納秒,69秒

    插入:50000條記錄
    insertData startTime:1387615577957
    insertData endTime:1474072398866
    相差:86458228630納秒,86秒

    插入:60000條記錄
    insertData startTime:1498220329120
    insertData endTime:1602732788105
    相差:104513895481納秒,104秒

    插入:70000條記錄
    insertData startTime:1713667130878
    insertData endTime:1834998856279
    相差:121333178658納秒,121秒

    插入:80000條記錄
    insertData startTime:1859249070482
    insertData endTime:1998321805424
    相差:139074161939納秒,139秒

    插入:90000條記錄
    insertData startTime:2025945141631
    insertData endTime:2182073256517
    相差:156129545235納秒,156秒

    插入:100000條記錄
    insertData startTime:2220057424616
    insertData endTime:2395134985871
    相差:175078943553納秒,175秒

    插入:120000條記錄
    insertData startTime:2658822511240
    insertData endTime:2866959720299
    相差:208138247459納秒,208秒

    插入:150000條記錄
    insertData startTime:2886769641392
    insertData endTime:3146130152016
    相差:259361930078納秒,259秒

    插入:180000條記錄
    insertData startTime:3482758554788
    insertData endTime:3795354906559
    相差:312598627479納秒,312秒

    插入:200000條記錄
    insertData startTime:4023631035788
    insertData endTime:4370300796888
    相差(用時):346671225253納秒,346秒

    插入:250000條記錄
    insertData startTime:4460471629494
    insertData endTime:4894180641115
    相差(用時):433710430516納秒,433秒

    插入:300000條記錄
    insertData startTime:4971718038186
    insertData endTime:5489207947378
    相差(用時):517491270818納秒,517秒

    ========================
    另外分享幾條刪除,更新的sql語句
    DELETE FROM cdb_posts where pid > 1000000
    DELETE FROM cdb_threads where tid > 1000000
    已刪除行數: 1262140 (查詢花費 130.2156 秒)
    UPDATE cdb_forums SET lastpost='0x74657374', threads=1000000, posts=1000000, todayposts=500001 WHERE fid=4;
    select pid from cdb_posts order by pid desc limit 1;

    ============================
    最后通過loadrunner模擬用戶點擊頁面普通頁面,和在100萬條數據的表下面查詢20條數據的頁面(通過后臺js調用設置就可以了)。

    希望官方和那位高手能整出更加高效,輕松實現的方法來。

    =================================================

    后來發現每個版塊最多只能1000分頁--雖然上面顯示了25000頁,但點到1000頁時后面就沒有分頁了,直接輸入1001就直接跳轉到1000也那里了。也就是說一個版塊前臺用戶看到的最多文章主題只有20000條。無法做到真正的100萬數據量(數據庫里面確實是100萬主題數)。

    最后發現這些越來是可以在后臺設置的。后臺-->全局-->界面與顯示-->主題列表頁-->每頁顯示主題數:
    主題列表中每頁顯示主題數目
    主題列表最大頁數:
    主題列表中用戶可以翻閱到的最大頁數,建議設置為默認值 1000,或在不超過 2500 范圍內取值,0 為不限制
    ==================================================================================
    后記:沒想到自己發的這篇文章受到這么多人的關注,順便對回復的問題作個概要回答:
    儲存過程是我一開始考慮到的,但為了模擬真實插入數據的效率后來否定了。
    Oracle SQL Loader 工具對這個應用沒有用,因為這個是要用來跟其他系統作對比的,使用的都是mysql,批量提交的方法也測試過了,受到文件大小的限制一次最多只能插入兩千條。
    非常歡迎給更多的人分享,如果轉載文章中能注明作者或網址就更好了。

    posted on 2008-09-16 18:16 流風 閱讀(10443) 評論(9)  編輯  收藏

    評論

    # re: 分享下自己用sql語句批量插入測試數據(企業級 百萬數據級別)的方法 2008-09-16 20:05 YZ

    一個儲存過程不就搞定了么?費這么大神?  回復  更多評論   

    # re: 分享下自己用sql語句批量插入測試數據(企業級 百萬數據級別)的方法 2008-09-16 20:22 gfh

    反復使用 insert into .... select ...語句來插入數據, 速度又快又好  回復  更多評論   

    # re: 分享下自己用sql語句批量插入測試數據(企業級 百萬數據級別)的方法 2008-09-17 01:37 站長論壇

    還不錯.....  回復  更多評論   

    # re: 分享下自己用sql語句批量插入測試數據(企業級 百萬數據級別)的方法 2008-09-17 10:32 skzr

    怎么不用批量提交?
    18W的時候需要3分鐘了  回復  更多評論   

    # re: 分享下自己用sql語句批量插入測試數據(企業級 百萬數據級別)的方法 2008-09-17 11:21 ∪∩BUG

    收藏備用..  回復  更多評論   

    # re: 分享下自己用sql語句批量插入測試數據(企業級 百萬數據級別)的方法 2008-09-17 14:17 Unmi

    Oracle 有 SQL Loader 工具很快的。  回復  更多評論   

    # re: 分享下自己用sql語句批量插入測試數據(企業級 百萬數據級別)的方法 2008-09-19 11:58 流風

    儲存過程是我一開始考慮到的,但為了模擬真實插入數據的效率后來否定了。
    Oracle SQL Loader 工具對這個應用沒有用,因為這個是要用來跟其他系統作對比的,使用的都是mysql,批量提交的方法也測試過了,受到文件大小的限制一次最多只能插入兩千條。  回復  更多評論   

    # re: 分享下自己用sql語句批量插入測試數據(企業級 百萬數據級別)的方法[未登錄] 2008-09-20 11:08

    你好 我是出版社的編輯,我看到你博客中的內容,感覺寫的非常好,如果想把這些內容和更多的人分享,可以和我聯系,把這些東西寫成書。現在有一本Java數據庫操作的書。
    我的郵箱:books_522008@yahoo.com.cn  回復  更多評論   

    # re: 分享下自己用sql語句批量插入測試數據(企業級 百萬數據級別)的方法 2008-11-10 15:09 keyboardsun@163.com

    效率真的太慢。太慢太慢了。用綁定變量,你的效率可以提高10倍,一般10萬條數據要控制在3秒以為,才能說湊合。  回復  更多評論   


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


    網站導航:
     
    <2008年11月>
    2627282930311
    2345678
    9101112131415
    16171819202122
    23242526272829
    30123456

    導航

    統計

    常用鏈接

    留言簿(1)

    隨筆檔案

    相冊

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国产麻豆成人传媒免费观看| 亚洲人成网站在线播放2019| 一级做a爰片性色毛片免费网站 | 在线日韩日本国产亚洲| 未满十八私人高清免费影院| 亚洲av日韩片在线观看| kk4kk免费视频毛片| 亚洲色偷拍区另类无码专区| 一级毛片a女人刺激视频免费| 亚洲一区视频在线播放| 免费人成毛片动漫在线播放| 无码久久精品国产亚洲Av影片| 高清一区二区三区免费视频| 亚洲黄色三级网站| 岛国大片免费在线观看| 污网站在线免费观看| 亚洲精品无码成人AAA片| 国产在线一区二区综合免费视频| 亚洲视频中文字幕| 精品无码国产污污污免费| 日日摸日日碰夜夜爽亚洲| 亚洲性在线看高清h片| 国产一级片免费看| www.亚洲成在线| 亚洲成A∨人片天堂网无码| 你是我的城池营垒免费看 | 亚洲性天天干天天摸| 成人免费视频网站www| 日韩欧美亚洲中文乱码| 国产亚洲精久久久久久无码77777 国产亚洲精品成人AA片新蒲金 | 一个人免费播放在线视频看片| 国产最新凸凹视频免费| 国产精品偷伦视频免费观看了| 亚洲欧洲日韩不卡| 国产精品国产午夜免费福利看| 国产免费黄色无码视频| 亚洲免费闲人蜜桃| 亚洲伊人久久综合影院| 免费精品国产自产拍在| jizz中国免费| 亚洲午夜精品久久久久久app|