Hoje vou falar sobre uma pequena mudança de código que pode significar megas e megas de dados e, conseqüentemente, de performance! ![]()
Suponhamos que você tenha um script que receba dados de sei lá onde e cadastre-os no MySQL, seria mais ou menos assim:
<?php
$usuarios = array();
$usuarios[] = array('nome' => 'Thiago', 'email' => 'contato@thiagobelem.net');
$usuarios[] = array('nome' => 'Fulano da Silva', 'email' => 'fulano@email.com');
$usuarios[] = array('nome' => 'Ciclano', 'email' => 'ciclano@uol.com.br');
// Inicia a variável
$cadastrados = 0;
// Para cada elemento de $usuários, faça:
foreach ($usuarios as $usuario) {
$nome = $usuario['nome'];
$email = $usuario['email'];
// Monta a consulta
$sql = "INSERT INTO `usuarios` (`id`, `nome`, `email`) VALUES (NULL, '{$nome}', '{$email}');";
// Executa a consulta verificando se foi inserido com sucesso
if (mysql_query($sql)) {
// Incrementa o contador
$cadastrados++;
}
}
echo 'Usuários cadastrados: ' . $cadastrados;
?>As consultas passadas para o MySQL ficariam mais ou menos assim:
INSERT INTO `usuarios` (`id`, `nome`, `email`) VALUES (NULL, 'Thiago', 'contato@thiagobelem.net'); INSERT INTO `usuarios` (`id`, `nome`, `email`) VALUES (NULL, 'Fulano da Silva', 'fulano@email.com'); INSERT INTO `usuarios` (`id`, `nome`, `email`) VALUES (NULL, 'Ciclano', 'ciclano@uol.com.br');
Não tem nada de errado com o código.. Funciona perfeitamente… Faz o contador direitinho.. Mas imagine se você tem 4000 registros pra inserir na tabela… Você vai rodar 4000 mysql_query() e vai deixar o seu MySQL maluquinho!
Não seria muito melhor fazer assim:
<?php
$usuarios = array();
$usuarios[] = array('nome' => 'Thiago', 'email' => 'contato@thiagobelem.net');
$usuarios[] = array('nome' => 'Fulano da Silva', 'email' => 'fulano@email.com');
$usuarios[] = array('nome' => 'Ciclano', 'email' => 'ciclano@uol.com.br');
// Início da consulta
$sql = "INSERT INTO `usuarios` (`id`, `nome`, `email`) VALUES";
// Para cada elemento de $usuários, faça:
foreach ($usuarios as $usuario) {
$nome = $usuario['nome'];
$email = $usuario['email'];
// Monta a parte consulta de cada usuário
$sql .= " (NULL, '{$nome}', '{$email}'),";
}
// Tira o último caractere (vírgula extra)
$sql = substr($sql, 0, -1);
// Executa a consulta
mysql_query($sql);
// Pega o número de registros inseridos
$cadastrados = mysql_affected_rows();
echo 'Usuários cadastrados: ' . $cadastrados;
?>A nossa consulta ficaria mais ou menos assim:
INSERT INTO `usuarios` (`id`, `nome`, `email`) VALUES (NULL, 'Thiago', 'contato@thiagobelem.net'), (NULL, 'Fulano da Silva', 'fulano@email.com'), (NULL, 'Ciclano', 'ciclano@uol.com.br')
Você pode fazer isso sem problema nenhum e com apenas uma “execução de consulta” você insere os três registros de uma só vez… Não é uma maravilha? ![]()
Você também vai gostar de ler:
- Relacionamento de Tabelas no MySQL
- Bloqueando visitantes pelo IP com MySQL e PHP
- Contador de visitas usando o MySQL
- Contador de visitantes online em PHP e MySQL
- Entendendo a paginação de registros no MySQL
Postado em Artigos, MySQL, PHP, Tutoriais
Com as tags Artigos, Código, Consultas, Contador, INSERT, Múltiplos, MySQL, Performance, PHP, Scripts, SQL, Tutoriais
Escrito por Thiago Belem
Gostou desse artigo?
Não se esqueça de assinar o RSS e divulgue-o para o mundo:

Boa tarde Thiago, otimo post.
Agora eu gostaria de saber no caso de um UPDATE como ficaria o código? Tentei implementar aqui mais não conseguir. Gostaria de sua ajuda nisso!
vlw Abraços!
Silvio
Com a função mysql_insert_id(), você pega o ultimo registro increment gerado.
Abraço
Gilmar,
com está função eu pego o último id inserido. Eu gostaria de pegar os últimos id´s que foram inseridos, no exemplo do blog é inserido na base de dados 3 registro “ao mesmo tempo”, eu gostaria de pegar o id gerado para cada um.
abrá
Olá,
gostaria de saber como eu faço para pegar o id de cada item que foi inserido neste seu exemplo.
abrços.
@Silvio
Não há uma forma simples de fazer isso.. Você precisaria fazer um SELECT depois.
O que vc pode fazer seria realizar uma contagem do ultimo id que esta em seu banco de dados, vamos supor que seja 50, então vc sabe que ele vai começar no 51, então vc pode utilizar um funcão do php para tratamento de array, e contar o numero de registros, assim você pode dizer que o registro numero 1 do array e no numero 51 do banco de dados, e assim sucessivamente, so que este tipo de script, teria de realizar uma exportação para uma outra tabela, ou para um arquivo de texto, xls. espero ter ajudado.
@Júlio
Tome cuidado… O fato do último ID da tabela ser 50 ou a tabela conter 50 registros não significa que o próximo ID será 51. O auto_increment existe… Podemos ter uma tabela vazia e o “próximo ID” poderia ser 83.
Ótimo, parabéns!
Muito bom! Mas gostaria de saber se funciona tambem para o comando UPDATE? E como ficaria o código?
Thiago,
Parabéns pelo trabalho realizado aqui no seu blog. Acabei de conhecer e já dei uma geral em quase todos os textos. Muito bom mesmo!
Como você respondeu para o Sergio, seria interessante sim fazer a quebra das inserções. Diria até obrigatório, no caso de inserções monstruosas.
O que acha de dar uma “soneca” para o servidor também, com sleep()? Ou seja, insere mil, “dorme”, insere mais mil e assim por diate. Como ficaria esse código?
Ah, mais ainda: como ficaria isso no CakePHP, que tem suas instruções padronizadas? O negócio seria fugir do padrão?
Sucesso cada vez maior!
@Danilo
É bom sim pausar o script, pode usar um sleep mesmo depois de uma cadeia grande de INSERTS…
Mais uma dica muito útil que já utilizei no meu sistema!
Vlw
Blz boy, mas assim, não teria o perigo (em pedidos super-mega-master-blaster gigantes) de um travamento do MySQL, com string’s ultra gigantes? ou talvez, estourar o tamanho da string, dar uma sobrecarga no servidor, chove granizo em Sergipe, sei la, não seria melhor tipo limitar essas super-pesquisas em pacotes de tamanho limitado (como por exemplo em pacotes de até 3.000)???
Flw, mt boa dica.
@Sergio
Sim.. Quanto a isso você está certo… Seria bom quebrar a cada 1000 inserções mais ou menos.
MAAARA.