Mysql
 sql >> Datenbank >  >> RDS >> Mysql

PDO - Großes Array in die MySQL-Datenbank einfügen

Obwohl ich immer noch bezweifle, dass Transaktionen und/oder gestapelte Einfügungen eine praktikable Lösung für Ihr Ressourcennutzungsproblem sind, sind sie immer noch eine bessere Lösung als die Erstellung massiver Erklärungen, wie Dave vorgeschlagen hat.

Probieren Sie diese aus und sehen Sie, ob sie helfen.

Im Folgenden wird davon ausgegangen, dass der Fehlerbehandlungsmodus von PDO so eingestellt ist, dass Ausnahmen ausgelöst werden. Beispiel:$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); Wenn Sie aus irgendeinem Grund den Ausnahmemodus nicht verwenden können, müssen Sie die Rückgabe von execute() überprüfen jedes Mal und lösen Sie Ihre eigene Ausnahme aus.

Einzeltransaktion:

$sql = $db->prepare("INSERT INTO players (name, level, vocation, world, month, today, online) VALUES (:name, :level, :vocation, :world, :time, :time, :online) ON DUPLICATE KEY UPDATE level = :level, vocation = :vocation, world = :world, month = month + :time, today = today + :time, online = :online");

$db->beginTransaction();
try {
    foreach ($players as $player) {
        $sql->execute([
            ":name" => $player->name,
            ":level" => $player->level,
            ":vocation" => $player->vocation,
            ":world" => $player->world,
            ":time" => $player->time,
            ":online" => $player->online
        ]);
    }
    $db->commit();
} catch( PDOException $e ) {
    $db->rollBack();
    // at this point you would want to implement some sort of error handling
    // or potentially re-throw the exception to be handled at a higher layer
}

Batch-Transaktionen:

$batch_size = 1000;
for( $i=0,$c=count($players); $i<$c; $i+=$batch_size ) {
    $db->beginTransaction();
    try {
        for( $k=$i; $k<$c && $k<$i+$batch_size; $k++ ) {
            $player = $players[$k];
            $sql->execute([
                ":name" => $player->name,
                ":level" => $player->level,
                ":vocation" => $player->vocation,
                ":world" => $player->world,
                ":time" => $player->time,
                ":online" => $player->online
            ]);
        }
    } catch( PDOException $e ) {
        $db->rollBack();
        // at this point you would want to implement some sort of error handling
        // or potentially re-throw the exception to be handled at a higher layer
        break;
    }
    $db->commit();
}