【MariaDB】セレクト結果をCSVにして、他のテーブルへCSVインポートする方法
まとめてインサートするならCSVを
全てCSVにして処理をすれば巨大データのインサートも速い。
バルクインサートなんてやらずにCSVインポートにしよう。
<環境>
・MariaDB:10.6.11
・PHP:8.2.1
・Ubuntu 22.04.1 LTS
1、セレクト結果をCSVにする方法
<セレクト文の最後に下記を追加するだけ>
INTO OUTFILE '/var/www/test.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"'
最後に上記を追加するだけでセレクト結果をCSVとして保存できます。
保存するCSVの場所と名前は「/var/www/test.csv」の部分。
区切り文字は「,」、囲い文字は「”」を指定しています。
2、CSVをインポートする方法
<こちらを実行>
LOAD DATA LOCAL INFILE \"/var/www/test.csv\" INTO TABLE testtable FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"';
PHPからMYSQLコマンドで実行する方法はこちらの記事に書いています。
PHPからMariaDBの「LOAD DATA LOCAL」でCSVインポートする方法
3、注意点:ループ処理をする場合
ループ処理をする場合は注意点があります。
・CSVは上書きできない
・ループ処理中にCSVを削除してもMariaDBはまだ存在するものと認識する
なぜか削除しても「ファイルが存在する(上書きできない)」と怒られます。
おそらくファイル情報がキャッシュに残っているからだろう。
したがって、「毎回ファイル名を変更する」必要があります。
<毎回ファイル名を変更する方法>
$Sqlcmd="LOAD DATA LOCAL INFILE \"/var/www/test".$i.".csv\" INTO TABLE outdata1 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"';\n";
都度csvファイルの名前を変数で変更する。
ループの番号にすると良いだろう。
全ての処理が終わった後削全部除すればいい。
<削除方法>
foreach (glob('/var/www/*.csv') as $removefile) {
unlink($removefile);
}
これでループでCSVを作成からのインポートという処理ができる。
バルクインサートよりプログラムも簡単になるのでおすすめです。
まとめ
セレクト結果を丸ごとCSVにできるので活用したい。
わざわざ変数にして1個1個処理する必要はありません。
CSVにして丸ごとインポートすればいい。
100万件をバルクインサートとか意味がわからない。
インポート関連は基本的にCSVで処理していこう。