doudonn WEB制作やサーバーの話とかいろいろ

PHPからMYSQLコマンドでMariaDBの「LOAD DATA LOCAL INFILE」でCSVインポートする方法

doudonn 更新日:
PHPからMYSQLコマンドでMariaDBの「LOAD DATA LOCAL INFILE」でCSVインポートする方法

「LOAD DATA LOCAL INFILE」でCSVインポートすると速い

INSERT処理として最速なのが多分LOAD DATA LOCAL INFILE
バルクインサートよりも速いので活用していこう。

PHPからPDOでも実行できますが、
別サーバーからMYSQLコマンドで実行する方法を紹介します。
(実験としてやったので記録するだけ)

※csvがDBサーバーにあるならLOAD DATA INFILEを使う方が速い

<環境>
・MariaDB:10.6.11
・PHP:8.2.1
・Ubuntu 22.04.1 LTS

実現したいこと

WEBサーバーからDBへCSVを送信してインポート

PDOじゃなくてMYSQLコマンドでログインしてやりたい。

PHPはシェルコマンドを実行することができるので、
ただPHPでubuntuを操るような感じです。
普通はPDOでやります。

なんでこんな方法をやろうと思ったのか?ですが、
MYSQLコマンドでインポートする方が速いのでは?という確認から。
実際、MYSQLから実行するとCPUを全部使うので速かったりする。

このあたりは是非確認してみてください。

1、まず、MYSQLコマンドをパスワード無しで使えるようにする

sudo visudo

#追記
nginx ALL=(ALL) NOPASSWD: /usr/bin/mysql

PHPのユーザーを「nginx」にしている場合です。
これでPHPから自由にMYSQLコマンドを使えるようになる。

2、SQLを書いたテキストファイルを作る

/var/www/sql.txt

LOAD DATA LOCAL INFILE \"/var/www/test.csv\" INTO TABLE testtable FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"';

MYSQLコマンドで実行するファイルを選択できるので、
SQLを書いたファイルを作成します。
この方法が汎用性あって一番良いと思う。

取り込むCSVは/var/www/test.csvの部分。
区切り文字は「,」、囲い文字は「”」を指定しています。

3、外部のDBへログインするためのファイルを作る

/var/www/db.txt

[client]
user = xxxxxxxxx
password = 'xxxxxxxxxxxxx'
host = 192.168.0.1

ログイン系のコマンドをこうしてファイルとして書いておくことができます。
パスワードの入力ができないので、おそらくこの方法しかない。

4、MYSQLコマンドで実行する

<PHP>

$cmd = 'sudo mysql --defaults-extra-file=/var/www/db.txt -D dbname < /var/www/sql.txt';

shell_exec($cmd);

これでMYSQLコマンドでログイン→外部DBサーバーへログイン→SQLの実行ができます。
ファイルの中身を都度「file_put_content」で作成しても良い。
そうすると変数で中身を変更できるので、ループ処理で違うSQLを実行できます。

以上

MYSQLコマンドだと何でもできるので覚えておきたい

シェルスクリプトでも可能とは思いますが、
自分はPHPの処理と合わせてやりたいのでPHPでやっています。
CSVの作成→CSVインポートという処理にすると実用的。

データ量が少ない場合はバルクインサートでも速度は大差無いですが、
数万件となるとCSVにした方が速いと思います。
セレクト結果をCSVにして、そのままインポートするだけなのでプログラムも簡単。

次回はその方法を書きたいと思います。

MariaDBの関連記事

記事一覧はこちら:MariaDB

管理人について
doudonn
名前:doudonn(どうどん)
ひたすらWEB制作な人。
一応社長です。音ゲー好き

プロフィール
お知らせ

2022年11月30日に全記事削除しました。
無駄にページ表示速度にこだわってます。

役立ちサイト
wiki

プライバシーポリシー・広告について


© 2022-2024 doudonn All Rights Reserved.