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回投げた場合

メモリ不足で落ちた。

結論

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

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

2017-08-03
formのinputでmaxlengthを使うとFirefoxでバグってた。他のブラウザでも気づかずにバグってたかもしれない。
2017-07-19
折れ線グラフをもう少しゆるやかに・・・というか何というか・・・調べていくと「移動平均」っていう言葉にたどり着いた
2017-07-10
FuelPHPの1.8をダウンロードして使っていたらセッションが使えないということに気付いた。
2017-06-27
MACにWin10をインストールしてみた:再挑戦。
2017-06-25
「簡単」っていうヤツらが多いけど・・・難しいぞ。