很多時候為了測試數據庫設計是否恰當,優化SQL語句,需要在表中插入大量的數據,怎么插入大量的數據就是個問題了。
最開始想到的辦法就是寫一個程序通過一個很大的循環來不停的插入,比如這樣:
int i = LOOP_COUNT; while(i-->=0){ //insert data here. }
不過我在這么做的時候發現這樣插入數據非常的慢,一秒鍾插入的數據量還不到100條,於是想到不要一條一條的插入,而是通過
INSERT INTO TABLE VALUES (),(),(),()...
這樣的方式來插入。於是修改程序為:
int i = LOOP_COUNT; StringBuilder stringBuilder; while(i-->=0){ if(LOOP_COUNT!=i && i%5000==0){ //通過insert values的方式插入這5000條數據並清空stringBuilder } stringBuilder.append("(數據)"); } //插入剩余的數據
這樣做的插入速度是上升了很多,不過如果想要插入大量的輸入,比如上億條,那么花費的時間還是非常長的。
查詢MySQL的文檔,發現了一個頁面:LOAD DATA INFILE 光看這個名字,覺得有戲,於是仔細看了下。
官方對於這個命令的描述是:
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
[REPLACE | IGNORE]
INTO TABLE tbl_name
[CHARACTER SET charset_name]
[{FIELDS | COLUMNS}
[TERMINATED BY 'string']
[[OPTIONALLY] ENCLOSED BY 'char']
[ESCAPED BY 'char']
]
[LINES
[STARTING BY 'string']
[TERMINATED BY 'string']
]
[IGNORE number LINES]
[(col_name_or_user_var,...)]
[SET col_name = expr,...]
命令不復雜,具體的每個參數的意義和用法請看官方的解釋 http://dev.mysql.com/doc/refman/5.5/en/load-data.html
那么現在做的就是生成數據了,我習慣用\t作為數據的分隔符、用\n作為一行的分隔符,所以生成數據的代碼如下:
long start = System.currentTimeMillis() / 1000; try { File file = new File(FILE); if (file.exists()) { file.delete(); } file.createNewFile(); FileOutputStream outStream = new FileOutputStream(file, true); StringBuilder builder = new StringBuilder(10240); DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); Random rand = new Random(); String tmpDate = dateFormat.format(new Date()); Long tmpTimestamp = System.currentTimeMillis() / 1000; int i = 0; while (i++ < LOOP) { if (i > 0 && i % 30000 == 0) { System.out.println("write offset:" + i); outStream.write(builder.toString().getBytes(CHARCODE)); builder = new StringBuilder(10240); } if (tmpTimestamp.compareTo(System.currentTimeMillis() / 1000) != 0) { tmpDate = dateFormat.format(new Date()); tmpTimestamp = System.currentTimeMillis() / 1000; } builder.append(tmpDate); builder.append("\t"); builder.append(rand.nextInt(999)); builder.append("\t"); builder.append(Encrypt.md5(System.currentTimeMillis() + "" + rand.nextInt(99999999))); builder.append("\t"); builder.append(rand.nextInt(999) %