PHPとMySQLでまとめてレコード取得と小分けに取得の比較

2015/02/26

クエリの投げる回数とその後のループ処理でどうすべきかで悩むので比較してみた。

やりたいことは「100万レコードに対して何か処理を行う」。

そのために、クエリを投げる回数と取得してくる件数の絡みでどっちが良いのかが知りたい。

試したソースは下記2種類のような感じ。

$pdo = new PDO(○○○○);
echo “MEMORY Fst: ” . number_format(memory_get_usage()) . ” byte” . “\n”;
$timeFst = microtime(true);

// 取得件数を減らして、クエリを10回投げる
$q = ‘select * from ○○○○ limit 10000;’;
for ( $i=0; $i<10; $i++ ) {
  $stmt = $pdo->prepare($q);
  if($stmt->execute()) {
    $dataAry = new StatementIterator($stmt);
    foreach ( $dataAry as $rowData) {
      // print_r($rowData);
    }
    unset($dataAry, $stmt);
  }
}

$timeEnd = microtime(true);
echo “MEMORY End: ” . number_format(memory_get_usage()) . ” byte” . “\n”;
echo “time: ” . bcsub($timeEnd, $timeFst, 5) . “\n”;

$pdo = new PDO(○○○○);
echo “MEMORY Fst: ” . number_format(memory_get_usage()) . ” byte” . “\n”;
$timeFst = microtime(true);

// 取得件数を減らさず、クエリを1回投げる
$q = ‘select * from ○○○○ limit 100000;’;
$stmt = $pdo->prepare($q);
if($stmt->execute()) {
  $dataAry = new StatementIterator($stmt);
  foreach ( $dataAry as $rowData) {
    // print_r($rowData);
  }
  unset($dataAry, $stmt);
}

$timeEnd = microtime(true);
echo “MEMORY End: ” . number_format(memory_get_usage()) . ” byte” . “\n”;
echo “time: ” . bcsub($timeEnd, $timeFst, 5) . “\n”;

「StatementIterator()」は「PDO イテレータで大量のデータを扱う」でまとめ中。

結果1

合計1万レコードに対して何かしたい。

「limit 1000」でクエリを10回投げた場合

MEMORY Fst: 313,616 byte
MEMORY End: 315,216 byte
time: 0.14270

「limit 10000」でクエリを1回投げた場合

MEMORY Fst: 313,328 byte
MEMORY End: 314,848 byte
time: 0.14380

結果2

合計10万レコードに対して何かしたい。

「limit 10000」でクエリを10回投げた場合

MEMORY Fst: 313,632 byte
MEMORY End: 315,232 byte
time: 1.44030

「limit 100000」でクエリを1回投げた場合

MEMORY Fst: 313,328 byte
MEMORY End: 314,840 byte
time: 1.54710

結果3

合計100万レコードに対して何かしたい。

「limit 100000」でクエリを10回投げた場合

MEMORY Fst: 313,616 byte
MEMORY End: 315,208 byte
time: 14.43940

「limit 1000000」でクエリを1回投げた場合

メモリ不足で落ちた。

結論

件数次第ってのもあるけど、クエリは複数回に分けたほうが速い。
メモリのことを考えると、どっちが良いとは言い切れない。まぁ、ケースバイケースってヤツだな。

新着(ニュース関連以外)

2018-05-16
PHPで画像のヘッダ情報(?)の「Orientation」を元に画像回転させたい。
2018-03-05
Android Studioをインストール。エミュレータを軽くするトコまで終わらせたかったけど、挫折した。
2018-02-23
プッシュ通知について調べてた時にでてきたServiceWorker。そのServiceWorkerについてのメモ。
2017-12-13
jqueryで取得したDOM要素をオブジェクトじゃなくて、配列で受け取りたい
2017-11-30
Xampp+FuelPHP1.8をサーバーにupしたらエラーになった。