Mysql
 sql >> Database >  >> RDS >> Mysql

PDO - Inserisci un array di grandi dimensioni nel database MySQL

Anche se dubito ancora che le transazioni e/o gli inserti in batch siano una soluzione praticabile al tuo problema di utilizzo delle risorse, sono comunque una soluzione migliore rispetto alla preparazione di dichiarazioni massicce come ha suggerito Dave.

Provali e vedi se aiutano.

Quanto segue presuppone che la modalità di gestione degli errori di PDO sia impostata per generare eccezioni. Es:$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); Se, per qualche motivo, non puoi utilizzare la modalità Eccezione, dovrai controllare il ritorno di execute() ogni volta e lancia la tua eccezione.

Singola transazione:

$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
}

Transazioni in batch:

$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();
}