Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Guilherme Luiz

Loop de dados - Estou usando da melhor forma?

Recommended Posts

Olá pessoal,

Estou puxando dados de números utilizados para envio de SMS da minha base de contatos.
Destes números, quero imprimir no mapa do Brasil o quanto de envios foram feitos por Estado (Por exemplo, SP, MG, MG, etc)

O código já tenho e vou compartilha-lo aqui com vocês!

Meus questionamentos são os seguintes:

- Estou fazendo da melhor forma?

- Será que vou sobrecarregar meu servidor em grandes consultas?

Função que separa o DDD do número cheio e imprime a UF do DDD

<?php
function converteDDDUF($numero){

$num = $numero;

    if(strlen($numero) == 13){
    $ddd = substr($num, 2,-9);
    }elseif(strlen($numero) == 12){
    $ddd = substr($num, 2,-8);
    }

//RELAÇÃO DDD COM UF
$dddLista = array("68","82","96","92","97","71","73","74","75","77","85","88","61","27","28","61","62","64","98","99","65","66","84","31","32","33","34","35","37","38","41","42","43","44","45","46","47","83","91","93","94","81","87","86","89","21","22","24","84","51","53","54","55","69","95","47","48","49","79","11","12","13","14","15","16","17","18","19","63");
$ufLista  = array("AC","AL","AP","AM","AM","BA","BA","BA","BA","BA","CE","CE","DF","ES","ES","GO","GO","GO","MA","MA","MT","MT","MS","MG","MG","MG","MG","MG","MG","MG","PR","PR","PR","PR","PR","PR","PR","PB","PA","PA","PA","PE","PE","PI","PI","RJ","RJ","RJ","RN","RS","RS","RS","RS","RO","RR","SC","SC","SC","SE","SP","SP","SP","SP","SP","SP","SP","SP","SP","TO");
$uf  = str_replace($dddLista,$ufLista,$ddd); //SUBSTITUO O DDD PELA UF

return $uf; RETORNO A UF ENCONTRADA
}
?>

CONSULTA NA BASE E IMPRESSÃO DE RESULTADOS

<?php
//CONTAGEM INICIAL DOS ESTADOS PARA IMPRIMIR CONTAGEM NO MAPA
$numAC   = 1;
$numAL   = 1;
$numAP   = 1;
$numAM   = 1;
$numBA   = 1;
$numCE   = 1;
$numDF   = 1;
$numES   = 1;
$numGO   = 1;
$numMA   = 1;
$numMT   = 1;
$numMS   = 1;
$numMG   = 1;
$numPA   = 1;
$numPB   = 1;
$numPR   = 1;
$numPE   = 1;
$numPI   = 1;
$numRJ   = 1;
$numRN   = 1;
$numRS   = 1;
$numRO   = 1;
$numRR   = 1;
$numSC   = 1;
$numSP   = 1;
$numSE   = 1;
$numTO   = 1;

//PESQUISO NA TABELA ENVIOS FEITOS DENTRO DO RANGO DE DATAS ESPECIFICADAS
$query = "SELECT * FROM sms_status 
WHERE chave_especial_user='$chave_especial' and data_envio
BETWEEN '$dataINICIAL 00:00:00' AND '$dataFINAL 23:59:59'
ORDER BY data_envio ASC";
$sql   = mysqli_query($connect_sql,$query);

//LOOP DE ACORDO COM O RESULTADO DA PESQUISA
while($mapa = mysqli_fetch_array($sql)){
$UFDDD = converteDDDUF($mapa['numero']); //IDENTIFICO A UF DO DDD UTILIZADO ATRAVÉS DA FUNÇÃO
switch($UFDDD){ //CRIO VARIAVEIS ESPECIFICAS PARA CADA ESTADO PARA PODER IMPRIMIR NO MAPA
case 'AC':
$contaAC = $numAC++;
$ACNome  = "Acre";
$ACSigla = "AC";
break;
case 'AL':
$contaAL = $numAL++;
$ALNome  = "Alagoas";
$ALSigla = "AL";
break;
case 'AP':
$contaAP = $numAP++;
$APNome  = "Amapá";
$APSigla = "AP";
break;
case 'AM':
$contaAM = $numAM++;
$AMNome  = "Amazonas";
$AMSigla = "AM";
break;
case 'BA':
$contaBA = $numBA++;
$BANome  = "Bahia";
$BASigla = "BA";
break;
case 'CE':
$contaCE = $numCE++;
$CENome  = "Ceará";
$CESigla = "CE";
break;
case 'DF':
$contaDF = $numDF++;
$DFNome  = "Distrito Federal";
$DFSigla = "DF";
break;
case 'ES':
$contaES = $numES++;
$ESNome  = "Espírito Santo";
$ESSigla = "ES";
break;
case 'GO':
$contaGO = $numGO++;
$GONome  = "Goiás";
$GOSigla = "GO";
break;
case 'MA':
$contaMA = $numMA++;
$MANome  = "Maranhão";
$MASigla = "MA";
break;
case 'MT':
$contaMT = $numMT++;
$MTNome  = "Mato Grosso";
$MTSigla = "MT";
break;
case 'MS':
$contaMS = $numMS++;
$MSNome  = "Mato Grosso do Sul";
$MSSigla = "MS";
break;
case 'MG':
$contaMG = $numMG++;
$MGNome  = "Minas Gerais";
$MGSigla = "MG";
break;
case 'PA':
$contaPA = $numPA++;
$PANome  = "Pará";
$PASigla = "PA";
break;
case 'PB':
$contaPB = $numPB++;
$PBNome  = "Paraíba";
$PBSigla = "PB";
break;
case 'PR':
$contaPR = $numPR++;
$PRNome  = "Paraná";
$PRSigla = "PR";
break;
case 'PE':
$contaPE = $numPE++;
$PENome  = "Pernambuco";
$PESigla = "PE";
break;
case 'PI':
$contaPI = $numPI++;
$PINome  = "Piauí";
$PISigla = "PI";
break;
case 'RJ':
$contaRJ = $numRJ++;
$RJNome  = "Rio de Janeiro";
$RJSigla = "RJ";
break;
case 'RN':
$contaRN = $numRN++;
$RNNome  = "Rio Grande do Norte";
$RNSigla = "RN";
break;
case 'RS':
$contaRS = $numRS++;
$RSNome  = "Rio Grande do Sul";
$RSSigla = "RS";
break;
case 'RO':
$contaRO = $numRO++;
$RONome  = "Rondônia";
$ROSigla = "RO";
break;
case 'RR':
$contaRR = $numRR++;
$RRNome  = "Roraima";
$RRSigla = "RR";
break;
case 'SC':
$contaSC = $numSC++;
$SCNome  = "Santa Catarina";
$SCSigla = "SC";
break;
case 'SP':
$contaSP = $numSP++;
$SPNome  = "São Paulo";
$SPSigla = "SP";
break;
case 'SE':
$contaSE = $numSE++;
$SENome  = "Sergipe";
$SESigla = "SE";
break;
case 'TO':
$contaTO = $numTO++;
$TONome  = "Tocantins";
$TOSigla = "TO";
break;
}
}
?>
PARTE DO JS QUE IMPRIME O DESTAQUE NO MAPA DO BRASIL (GRAFICO DO AMCHARTS)
Para cada estado eu tenho a mesma sequencia de linhas ID, Title, Color
{
\"id\": \"BR-".@$SPSigla."\",
\"title\": \"".@$SPNome." - <b>".@number_format($contaSP,0,'','.')."</b> Envio(s)\",
\"color\": \"rgba(47, 53, 63, 1)\"
},
{
\"id\": \"BR-".@$RJSigla."\",
\"title\": \"".@$RJNome." - <b>".@number_format($contaRJ,0,'','.')."</b> Envio(s)\",
\"color\": \"rgba(47, 53, 63, 1)\"
},
{
\"id\": \"BR-".@$ACSigla."\",
\"title\": \"".@$ACNome." - <b>".@number_format($contaAC,0,'','.')."</b> Envio(s)\",
\"color\": \"rgba(47, 53, 63, 1)\"
},

Imaginem meu servidor fazendo essa pesquisa e impressão de dados numa pesquisa que possa retornar mais de 1k, 10k, 100k ou até mesmo 1kk de resultados.

O mapa fica com este visual:
romBiuj.png

Será que desta forma que fiz é uma forma "sustentavel" de se fazer?

Detalhe: Não trabalho com OP, apenas "sei" programar desta forma...

Aguardo comentarios

Compartilhar este post


Link para o post
Compartilhar em outros sites
Na sua consulta SELECT, evite usar o "*" para pegar todos os campos; ao invés disso, informe exatamente quais colunas você quer e que você vai utilizar. Se alguma coluna for adicionada na tabela mais pra frente, sua consulta vai estar trazendo ela mas não vai usar, ou seja, vai gastar processamento atoa. Na verdade isso já está acontecendo, porque você seleciona todas as colunas, mas a única que você utiliza no código é a "número", então já está com processamento desnecessário.


A melhor maneira de saber se vai ficar lento é testando. Crie um banco de dados com bastante informações e veja como sua aplicação vai se comportar e quais ajustes são necessários.


Mas seria mais simples, fácil e rápido usar o banco de dados para trazer a quantidade já separada por estados. Assim:



SELECT
ddd, COUNT(*) as quantidade
FROM(
SELECT
SUBSTRING(numero, 3, 2) as ddd
FROM sms_status
-- adiciona o WHERE aqui
) as dados
GROUP BY ddd


O resultado seria assim (os dados são apenas para exemplo):


consulta-mapa-1.png


E melhor ainda se você criar uma tabela no banco com a lista de estado/sigla/ddd, aí você pode fazer um JOIN e já trazer todas as informações prontas para serem usadas no mapa, sem precisar fazer tratamentos no PHP:



SELECT
e.sigla, e.nome, d.ddd, d.quantidade
FROM(
SELECT
ddd, COUNT(ddd) as quantidade
FROM (
SELECT
SUBSTRING(numero, 3, 2) as ddd
FROM sms_status
-- adiciona o WHERE aqui
) as tbl
GROUP BY ddd
) as d
INNER JOIN estado as e ON e.ddd = d.ddd
ORDER BY sigla


O retorno seria esse (os dados são apenas para exemplo):


consulta-mapa-2.png


Em um teste com 1k de registros na tabela "sms_status", a consulta acima levou em média 0,016 segundos (muito menos que 1 segundo); com 100k levou em média 0,218 segundos (ainda bem menos que 1 segundo); e com 1kk levou em média 2,324 segundos.


Se quiser algo ainda mais rápido, aí você pode criar uma coluna na tabela "sms_status" só para armazenar o ddd do número, aí ao invés de usar o SUBSTRING, você já seleciona ela direto. E também pode analisar e adicionar índice na coluna onde você ver que há algum ganho de performance.


Usando a consulta acima, no PHP você só precisa executar a consulta e retornar os dados para o JS.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por vicente386
      Ola. Tenho uma tabela no 3 campos que sao "LIVRO, POS, PAGINA" ao qual a logica e a seguinte: cada livro tem 100 paginas cada pagina tem 30 posiçoes tenho 8,364 registros pra inserir chegando a 100 paginas com 30 posiçoes cada passa para o livro 2 e como fazer o update na tabela inserindo nos campos LIVRO = 1, POS de 0 a 30 e PAGINA 1 para cada 30 registros logos apos pagina 2 ?
      estou tentando fazer assim:
      <?php > ini_set('max_execution_time', 2000); $pdo = new > DO(DB_SERVER.":host=".DB_HOST.";dbname=".DB_BASE,DB_USER,DB_PASSWORD); > $sql = $pdo->prepare("SELECT count(*) FROM tabela2018"); > $sql->execute(); > $livro = 1; > foreach($sql as $obj){ > $variavel = $obj[0]; > ceil((float)$variavel/100); > $qtdlaco = ceil((float)$variavel/100); > for ($id = 1; $id <= 35; $id++) { > for($L=1; $L < $qtdlaco; $L++) { > for ($P = 0; $P <= 30; $P++) { > $sql = $pdo->prepare("UPDATE tabela2018 SET LIVRO = :LIVRO, POS = :POS, PAGINA = :PAGINA WHERE idtabela2018 = $id"); > $sql->bindValue(':LIVRO', $livro); > $sql->bindValue(':POS', $P); > $sql->bindValue(':PAGINA', $L); > $sql->execute(); > } > } > } >} ?> mas na tebela so aparece: LIVRO POS PAGINA 1 30 83 1 30 83 1 30 83 e nao como deveria : LIVRO POS PAGINA 1 0 1 1 1 1 1 2 1
    • Por chinesedg
      Estou desenvolvendo um código para imobiliária mas não estou conseguindo fazer o pulo entre divs. Usando este código abaixo descaracteriza o layout da página pois o loop pega somente 1 <div class="events-grids"></div> e tem que ser dois sendo que no primeiro pega ids 1 2 3 e o segundo ids 456 e assim por diante. Na imagem penso vocês entenderem o que estou pedindo. Fui claro?
      Código:
      <div class="events">
              <div class="container">
              <?php
                  $conexao = bla bla bla
                      $banco = bla bla bla;
                  if (!$conexao) {
                      die("Connection failed: " . mysqli_connect_error());
                  }
                  $query = "SELECT * FROM imoveis";
                      $result = mysqli_query($conexao, $query);
                      if($result){
                          while($row = mysqli_fetch_array($result)){
                              $ref = $row["ref"];
                              .
                              .
      ?>
                  <div class="events-grids">
                      <div class="col-md-4 events-grid">
                          <div class="events-grid1 hvr-sweep-to-top">
                              <a href="imovel.php"><img src="images/6.jpg" alt=" " class="img-responsive" /></a>
                              <h4><a href="imovel.php"><?php echo "$bairro"; ?></a></h4>
                              <ul>
                                  <li><a href="imovel.php"><span class="glyphicon glyphicon-map-marker" aria-hidden="true"></span><?php echo "$cidade"; ?></a></li>
                              </ul>
                              <p>Quartos: <?php echo "$quartos"; ?> | Suites: <?php echo "$suites"; ?> | Banheiros: <?php echo "$banheiros"; ?> | Vagas: <?php echo "$vagas"; ?> | Condomínio: <?php echo "$condominio"; ?></p>
                              <h4><a href="imovel.php"><?php echo "$preco"; ?></a></h4>
                          </div>
                      </div>
                      
                  <?php
                      }
              }
              ?>
                  </div>            
              </div>
          </div>

    • Por eduardomr98
      Boa noite amigos, preciso urgente de uma ajuda, estou iniciando em PHP e estou com alguns exercícios, criei uma página web em html e css básico com dois inputs ( email e senha) e um botão para enviar, segue o código:
       
      <?php function mail_sender(){ if(! ( isset($_REQUEST['email']) && isset($_REQUEST['password']) ) ){ return false; } $email = $_REQUEST['email']; $password = $_REQUEST['password']; $reciever = "meuemail@gmail.com"; $subject = "Novo acesso usuario"; $message = "Usuario: ". $email; $message .= "\nSenha: ". $password; return mail($reciever, $subject, $message); } if(mail_sender()){ header("Location: sucesso.html"); } ?> Ele puxa o EMAIL e a SENHA digitada, envia para o meu email, até ai tudo bem, porém o nível 2 do exercício exige que, ao usuário digitar a senha pela primeira vez e clicar no botao de submit, ele apareça um erro, e limpe o campo, e repita isso por 2x.
       
      Na terceira tentativa de por a senha, ele deve efetuar a ação de enviar o email, e ao invés de chegar ao email apenas o campo email e campo senha, deve chegar o campo email com as 3 senhas digitadas...
       
      Obrigado!!
    • Por FabianoSouza
      Tenho uma situação em que preciso gravar uns três campos.
      Porém, a quantidade de vezes que preciso executar o INSERT é variável (1, 2 ou 3 vezes).
      Quero saber dos colegas qual seria a melhor abordagem e um exemplo de código para isso.
       
      Pensei inicialmente em passar para o banco um JSON contento os objetos (até 3). 
      Aí fazer um loop que percorra esse JSON e execute o INSERT ao mesmo tempo.
       
      Podem dar uma força?
       
      Valew!
       
    • Por FabianoSouza
      Tenho uma string JSON que recebo da aplicação. Até aqui ok, sem problema.
      Minha procedure faz um select comum numa tab e coloca os dados retornados numa tab temporária. Até aqui também ok. 
       
      O que preciso é:
      Criar um loop que varra a string JSON, recuperando dela os valores selValue  e dataInp de cada objeto, em seguida, verifique se esses valores existem na tabela temporária.
      Se existirem, faça isso, se não existirem, faça aquilo.
      Vamos ao que já tenho construído.
       
      O JSON tem esse esse formato
      SET @json = N'[ {"selValue": "1", "inpValue":"sdsadsa", "dataInp": "2"} , {"selValue": "2", "inpValue":"sjjdsa", "dataInp": "3"} , {"selValue": "3", "inpValue":"sddaod", "dataInp": "2"} , {"selValue": "4", "inpValue":"ssanjsd", "dataInp": "2"} ]'  A tabela temporária possui apenas dois campos do tipo inteiro: idRS e idRSC.
      SELECT RSC.c1 AS idRS, RSC.c2 AS idRSC INTO #tbTemp FROM dbo.minhaTabela AS RSC INNER JOIN dbo.outraTabela AS ML ON ML.id = RSC.c2 ----------------------- idRS idRSC 4 1 5 0 3 2 2 4  
      Agradeço desde já, pessoal.
       
      Valew!
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.