大數據量生成腳本及導入策略
性能測試過程中,如果需要構造一張表大數據量基礎數據時,有兩點需要注意:如何生成unl文件(此文件是後綴為.unl的數據文件,格式為,按表列分割的數據記錄,例如:10001|33333|),生成的unl文件是否可以一次性導入到數據庫相應表中。
為了方便敘述,假設數據庫存在表test(id integer,name integer,primary key(id,name))。若想為此表導入1000W條記錄,手動insert不現實,一般數據庫系統都會提供特定指令,實現數據的導入導出操作,我們可以預先構造好相應格式的unl文件,再調用數據庫導入指令,實現數據的快速導入。以Informix數據庫為例,數據導入操作的命令為:load from testdata.unl insert into test;現在,剩下的問題就是如何生成一千萬行的unl文件了。
了解shell腳本的同學會很快想到使用awk實現,這裡也如大家所想,使用awk實現:
[plain]
<span style="">#!/bin/sh
awk 'BEGIN{
dbfile=sprintf("testdata.unl");
for(i=0; i<1000; i++)
{
for(j=0;j<10000;j++)
{
printf "100%05d|9%08d|\n",i,j >>dbfile
}
printf "%d completed.\n",i
}
}' /dev/null</span>
這樣,會生成一個有1000W條記錄的unl文件,於是我們興沖沖使用“load from testdata.unl insert into test;”指令導入數據,結果發現報錯了。因為一次性導入的數據太多,數據庫系統的緩存、日志系統空間不夠用,無法一次性記錄太多的記錄(或者因為操作時間太長,直接超時了“Long transaction aborted”)。
有兩種解決方案:提高緩存、日志系統大小;縮小單個unl數據量。顯而易見,後者更為合理。
如果將一千萬的unl分成100小份,每份10W條,就好處理多了。腳本略作修改,如下:
[plain]
<span style="">#!/bin/sh
awk 'BEGIN{
for(i=0; i<100; i++)
{
dbfile=sprintf("mytable%02d.unl",i);
for(j=0;j<100000;j++)
{
printf "100%05d|9%08d|\n",i,j >>dbfile
}
printf "%d completed.\n",i
}
}' /dev/null</span>
此時,面對100個文件,要操作一百次,又有點頭大。本著偷懶的原則,自然想到使用自動去做。於是,自動導入到test表中的shell腳本也新鮮出爐:
[plain]
<span style="">#!/bin/sh
#生成100條的sql腳本
awk 'BEGIN{
dbfile=sprintf("loadData.sql");
for(i=0; i<100; i++)
{
printf "load from mytable%02d.unl insert into test;",i >>dbfile
}
printf "completed."
}' /dev/null
#執行腳本
dbaccess mydatabank loadData.sql
</span>
當然,如果想更深一步“偷懶”,可以把這些shell放一起,不過要注意可讀性,建議再新建一個shell,順序調用這兩個shell,便於後續維護。