【サクッと解説】PHP fetchAllとfetchの違いと使い分け

目次

1. 本記事のポイント

  • PHPのPDOにおけるfetch()fetchAll()の違いを実例付きで解説
  • データ件数やメモリ効率など、使い分けの判断基準を提示
  • 実務での選定ミスによる影響やパフォーマンス面の注意点も紹介

2. PHPのfetchAllとfetchとは?

PHPのPDOクラスには、データベースから結果を取得するためのfetch()fetchAll()という2つの代表的なメソッドがあります。

いずれもSQL実行後に結果セット(ResultSet)を取得するために使われますが、取得方法とデータ量に大きな違いがあります。

fetch()は1行ずつ順に取得するのに対し、fetchAll()は全行を一括で取得します。この違いにより、実行時のメモリ使用量や処理パフォーマンス、そして適用できる場面に差が生まれます。

実務では、結果件数が数万件以上になる場合やストリーミング処理が必要な場合はfetch()が適しており、数件〜数十件程度の固定サイズのデータ取得ではfetchAll()の方が扱いやすいことが多いです。

3. 詳細解説

単一行ずつ処理したいときのfetch()

データを1件ずつ処理する必要がある場合はfetch()を使用します。

PHP
<?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'pass');
$stmt = $pdo->query('SELECT id, name FROM users');

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    // 1行ずつ表示する
    echo $row['id'] . ": " . $row['name'] . "\n";
}

出力例:

1: 山田
2: 佐藤
3: 鈴木

この方法は、行数が多い場合でもメモリ効率が良く、逐次処理にも適しています。

一括取得で全体を扱いたいときのfetchAll()

全件を配列で一括取得したいときにはfetchAll()を使います。

PHP
<?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'pass');
$stmt = $pdo->query('SELECT id, name FROM users');
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

foreach ($rows as $row) {
    echo $row['id'] . ": " . $row['name'] . "\n";
}

出力はfetch()と同様ですが、取得時点で全データを配列に保持するため、大量データではメモリを圧迫します。

結果の件数で適切に使い分ける

以下は100万件のデータを取得するケースです:

PHP
<?php
$stmt = $pdo->query('SELECT * FROM large_table');

// 推奨されない方法(fetchAll)
$allRows = $stmt->fetchAll(); // 数GBのメモリ消費の可能性

// 推奨される方法(fetch)
while ($row = $stmt->fetch()) {
    // 各行を順に処理
}

このように、行数が非常に多い場合はfetch()を使ってストリーミング処理を行うのが基本です。

fetch vs fetchAllの比較と選定基準

項目fetch()fetchAll()
処理方式1行ずつ全行まとめて
メモリ使用少ない多い(件数依存)
コードの簡潔さやや冗長簡潔
件数が多い場合×
小規模な結果セット

実務上は、件数・パフォーマンス・処理の構造(逐次処理か一括処理か)に応じて選定します。

4. よくあるミス・誤解・落とし穴

fetchAll()は簡潔で扱いやすいため、初心者に好まれがちですが、大量のデータを一括取得してしまうとPHPのメモリ上限(デフォルト128MB程度)を簡単に超えてしまうリスクがあります。

また、fetch()を使っているつもりでも、fetchAll()で既に結果セットを消費していた場合、fetch()では何も取得できません。PDOのステートフルな性質を理解し、どの段階でどのメソッドを使うかを意識する必要があります。

さらに、fetch()をループ内で使用する際に、想定より少ない件数しか処理されない場合は、SQLのLIMITや条件句による制限の見落としも疑うべきです。

5. まとめ

  • fetch()は1行ずつ処理する場面、fetchAll()は全体をまとめて扱う場面で使い分ける
  • 大量件数ではfetch()が安全で高効率、fetchAll()はメモリ使用に注意が必要
  • 実務では件数規模・処理構造・メモリ制限を考慮した選定が重要
  • 1つのステートメントで両方を混在使用しないよう注意
よかったらシェアしてね!
  • URLをコピーしました!
目次