前回記事に続いて、データベースの処理速度を調査してみました。
今回は、前回作成したテーブルに、PHP 経由で、郵便番号 CSV のデータ(記事作成時点では 124,269行)を1行づつ INSERT INTO で実行してみました。
コードは、こちら
<?php
// データベースへ接続
$mysqli = mysqli_connect('localhost', 'root', 'root', 'bench');
mysqli_set_charset($mysqli, 'utf8mb4');
// テーブル削除
$sql = 'TRUNCATE TABLE jzip;';
$mysqli->query($sql);
// 計測開始時間
$time_start = microtime(true);
// CSV からデータ読み込んで、テーブルに保存
if (($handle = fopen("utf_all.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) {
$stmt = $mysqli->prepare('INSERT INTO jzip (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);');
$stmt->bind_param(
$data[0],
$data[1],
$data[2],
$data[3],
$data[4],
$data[5],
$data[6],
$data[7],
$data[8],
$data[9],
$data[10],
$data[11],
$data[12],
$data[13],
$data[14],
);
$stmt->execute();
}
fclose($handle);
}
$mysqli->close();
$time_end = microtime(true);
$time = $time_end - $time_start;
var_dump($time);
それぞれ、5 回実行した結果、結果を疑うくらいに処理時間に差が出ました。
InnoDB(単位:秒)
740.45
738.31
740.09
741.34
739.87
MyISAM (単位:秒)
14.06
13.69
14.35
13.81
14.11
InnoDB の方は、あまりに遅い気がしたので、メモリスワップでもして遅くなってるのかな?と思ったんですが、vmstat を見る限りスワップは発生してないようなので、オンメモリで実行してこの差が出てるということだと思われます。
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 1 0 2207500 8596 923056 0 0 1 5 24 59 0 0 100 0 0
ということで、INSERT INTO での一括インポートは、MyISAM の方が随分と早いようです。
ただ、別のシナリオでは、InnoDB が有利なケースもあると思うので、インポートはMyISAMで行って、運用はInnoDB で行うというよな形も考えられると思うので、引き続き、調べていこうと思います。
★メモ:そこまで長い文字列の住所は無いだろうと思っていたら、一番長い住所は、結構長かった。
36207,"77121","7712102","トクシマケン","ミマシ","ミマチョウ(イエノマエ、オオイケ、オオウエ、オオキタ、オオサコ、オオマエ、オカノウチ、オシアゲ、カヤバラ、カワノウエ、カンノン、クリバヤシ、クロスナ、サルガウチ、サルサカ、シモシロジ、シロジ、スミガマ、セリザコ、ソウゴ、ソウダ、ソトバカ、タキノウエ、タツミヤマ、タノオカ、タンザカ、ナカオカ、ナカノタノイ、ナカヨコオ、ナガジ、ニシウラ、ニシノタニ、ノタノイ、ハシダニ、バシトコ、ヒガシスジ、ヒラオ、ヒラノ、フジユウ、マエザカ、ミズノオカ、ミソガクボ、ミチノウエ、ミヤノオカ、ムナバタ、ヤクシガクボ、ヤマニシヤシキ、ヤマハシダニ、ヨコオ)","徳島県","美馬市","美馬町(家ノ前、大池、大上、大北、大佐古、大前、岡ノ内、押上、茅原、川ノ上、観音、栗林、黒砂、狙ケ内、猿坂、下白地、白地、炭釜、芹佐古、惣後、惣田、外墓、滝ノ上、立見山、田ノ岡、狙坂、中岡、中野田ノ井、中横尾、長地、西浦、西ノ谷、野田ノ井、橋谷、場シ所、東筋、平尾、平野、藤宇、前坂、水ノ岡、味噌ケ久保、道ノ上、宮ノ岡、南畠、薬師ケ久保、山西屋敷、山橋谷、横尾)",1,0,0,0,0,0