きっかけ
大量のデータを投入してテストをしてみたいと思い、まずは大量のデータを投入してみることにしました。
結論からいうと、こんな感じに
select count(*)して1000万件を確認
700MBのcsvファイルを投入して30秒ほどでinsert完了しました。
もっと時間かかるかと思いましたが、早い!
テストのテーブルを作成する
適当にテーブルを作成
インデックスはまだ作りません。
CREATE TABLE public.test (
id character varying(256) NOT NULL,
num integer,
created_at timestamp with time zone
);
CSVは以下のようなものを作ります
↓sql_many.csvの中身
id,num,created_at
c6afae11-6be6-4f5b-b9c6-6e626b299301,9149,2019-06-02 10:34:59+00
...省略
pythonでcsv作成プログラムを作ってみる
ランダムなデータを入れ込んでいます。
日付はちょっと適当かも。
最初、大量のinsert into命令を作成するプログラムを作っていたのですが、CSVファイルimportしたほうがinsert処理時間が早いためcsv作成プログラムに変更しました
(途中で変更したのでpythonのcsvライブラリを使っていない・・)
↓sql.pyを作成
import string
import uuid
import datetime
import random
#開始関数
def main():
fileName = 'sql.csv'
maxRowNum = 1000 * 10000
createCsvFile(fileName, maxRowNum)
#追記モードでファイルに書く
def createCsvFile(fileName: string, maxRowNum: int):
with open(fileName, 'at') as fb:
header = createHeader()
fb.write(header)
for rowNum in range(maxRowNum):
sql = getOneSql(rowNum)
fb.write(sql)
print(str(rowNum) + ' - ' + sql)
fb.close()
#ヘッダーを作成
def createHeader():
return "id,num,created_at\n"
#1件分のCSV作成
def getOneSql(num: int) -> string:
#GUID作成
csv = ''
csv += str(uuid.uuid4())
csv += ','
#ランダムな数字
csv += str(random.randrange(0, 10000 +1, 1))
csv += ','
#ランダムな日付を作成
csv += random_date(datetime.datetime(2018, 1, 1), datetime.datetime(2021, 2, 1)).replace(tzinfo=datetime.timezone.utc).isoformat()
csv += '\n'
return csv
#ランダムな日付を作成する関数 他サイトから拝借
def random_date(start, end):
"""Generate a random datetime between `start` and `end`"""
return start + datetime.timedelta(
# Get a random amount of seconds between `start` and `end`
seconds=random.randint(0, int((end - start).total_seconds())),
)
#開始する
main()
#実行
python 3.10.0で実行しました
2-3分かかります。
csvは700MB近くになります。
python sql.py
#pgAdmin 4でimport
1.対象のテーブルで右クリック
2.Import/Exportを選択
3.以下の画面が開くので、設定して終わり
#これから
SQLを実行して、どのぐらい時間がかかるか、実行計画などを見ていこうと思います
#参考
Generate a random date between two other dates
https://stackoverflow.com/questions/553303/generate-a-random-date-between-two-other-dates/26883710#26883710