數據庫插入百萬數據

這是對一次數據庫作業的深究

首先說一下作業題目要求:


建立一張包含四個字段的表,表名爲test

         第一列爲id,主鍵,自增。

                第二列爲col1,隨機爲MikeBobJackAliceCathyAnnBettyCindyMaryJane中的一個

                第三列爲col2,隨機爲一個5位字母,字母限制在a-e

                第三列爲col3,隨機爲一個1-20之間的整數

按照步驟一中對錶的要求插入100萬條記錄,記錄執行的時間

 

對要插入的數據範圍進行一定的預處理


(1)對於col1,創建取值範圍數組


隨機獲取的時候只要調用 col1Values[(int)(Math.random()*10)] 即可。

 

(2)對於col2,通過遞歸創建取值範圍數組

隨機獲取的時候只要調用col2Values[(int)(Math.random()*3125)]即可。

(3)對於col3,隨機獲取的時候只要(int)(Math.random()*20)+1即可。

 

 

插入大數據量的數據

(1)首先想到的方法當然是傳統的一行一行的插入方法:通過Connection獲得Statement,再調用Statement對象的execute函數執行sql語句,插入一行,這樣循環100萬次即可,但是時間複雜度太高,估計沒有個把小時是搞不定的。

 

(2)然後想到了對sql語句進行預處理,於是很大程度上提高了效率。下面是這部分代碼的核心部分。

測試結果如下:

start insert data
end insert data
insert time: 110.215 s

(3)對於上面的結果還是不太滿意,於是便開始了探索。

 

(a)從網上看到一個方法,使用在PreparedStatement 類上的addBatch(),executeBatch()方法,通過批量處理,可以一次性的將1000甚至10000sql插入操作作爲一個事務進行批量優化,並且作者在oracle的數據庫上測試過時間是低於10s的。於是我也嘗試了一下,發現依然是107s左右,於是便迷茫了。

 

(b)這個時候看到網上的另外一篇文章,解釋了爲什麼MySqlJDBC驅動不支持批量操作,原來Mysql不支持addBatch(),executeBatch()等方法的批量優化,而Oracle則數據庫支持,並且可以在360 ms左右的時間插入100萬條記錄

網址:http://elf8848.iteye.com/blog/770032

 

(c)後來看到葛班長的日誌,他通過PythonSQLite中插入100萬條數據只用了4秒,原因在於Python對所有的這100萬條插入語句進行了優化,將所有的插入操作放到了同一個事務中,這樣極大的減少了開啓和取消事務的時間,而正是這部分操作會消耗大量的時間。

網址:http://aegiryy.net/?p=380

 

(d)於是我受到了啓發,並且瞭解到對於Mysql數據庫的操作時,一個sql插入語句中可以插入多行數據。於是我嘗試通過StringBuffer構造一個比較大的sql語句,每個語句可以插入1萬行的數據(如果是10萬或者100萬的話會超出堆內存限制),這樣循環100次即可完成插入。下面是這種方法的核心代碼:

測試結果如下:

start insert data
end insert data
insert time: 15.083 s

 

(e)最後我想到了再將這種方法優化,採用預處理的方式,在代碼易讀性和效率上都有所提高,雖然效率提高的不多。下面是這個方法的核心代碼:

 

測試結果如下:

start insert data
end insert data
insert time: 14.47 s

 

最後貼出最終個解決方案的所有代碼:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章