Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

PDO - Inserir grande array no banco de dados MySQL


Embora eu ainda duvide que transações e/ou inserções em lote sejam uma solução viável para seu problema de uso de recursos, elas ainda são uma solução melhor do que preparar instruções massivas como Dave sugeriu.

Dê uma chance a estes e veja se eles ajudam.

O seguinte assume que o modo de tratamento de erros do PDO está definido para lançar exceções. Por exemplo:$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); Se, por algum motivo, você não puder usar o modo de exceção, precisará verificar o retorno de execute() cada vez e lance sua própria exceção.

Transação única:
$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
}

Transações em lote:
$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();
}