Ir para conteúdo
Fórum Script Brasil
  • 0

A última entrada de cada item


Frank K Hosaka

Pergunta

Eu tenho um projeto chamado Orçamento, e dentro dele eu tenho uma rotina chamada baixa de estoque, mas ele é lento no PHP e mais ainda no Laravel.

Passei o dia todo pensando numa nova rotina, agora com a ajuda do copilot.microsoft.com

Talvez seja possível obter a última entrada de cada item pelo MySQL, mas eu pedi para o Copilot desistir da ideia.

Eu montei uma consulta de todos itens que entraram no mês. A partir daí pedi para o Copilot montar um vetor que pegasse a última entrada de cada item.

A rotina do Copilot começa com $ultimo=[ ] e pega todo o ciclo do foreach($previa as $prod). Ele é muito bacana, parece que funciona, só não sei ainda como conferir, mas é bem mais rápido que a rotina que inventei antes do Copilot aparecer:

<?php
$pdo=new PDO("mysql:host=localhost;dbname=teste","root","");
$inicio=date('2024-10-01');
$fim=date('2024-10-31');
$previa=$pdo->query("SELECT * FROM tbhistprod 
        WHERE custototal > 0 And dia BETWEEN '$inicio' and '$fim'
        order by dia desc")->fetchAll(PDO::FETCH_ASSOC);
$ultimo = [];
foreach ($previa as $prod) 
{
    if (!isset($ultimo[$prod['codprod']]) || 
        $prod['dia'] > $ultimo[$prod['codprod']]['dia']) 
    {
        $ultimo[$prod['codprod']] = $prod;
    }
}
?>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" 
    rel="stylesheet">
<table class='container mt-5 table table-striped table-sm'>
    <th class=text-end>CodProd
    <th>Descrição
    <th class=text-end>Lcto
    <th class=text-end>Qt
    <th class=text-end>Custo
    <th class=text-end>Estoque
    <th class=text-end>Total
    <th>História
<?php foreach ($ultimo as $prod):
$detalhe=$pdo->query("select * from tbprod where codprod=".$prod['codprod'])
                ->fetch(PDO::FETCH_OBJ);
$hist=$pdo->query("select * from tbdiario where lcto=".$prod['lcto'])
                ->fetch(PDO::FETCH_OBJ);
$total=$pdo->query("select sum(custototal) as soma from tbhistprod 
                where codprod=".$prod['codprod'])
                ->fetch(PDO::FETCH_OBJ)->soma;
?>
    <tr><td class=text-end><?=$prod['codprod']?>
        <td><?=$detalhe->prod?>
        <td class=text-end><?=$prod['lcto']?>
        <td class=text-end><?=$prod['qt']?>
        <td class=text-end><?=$prod['custototal']?>
        <td class=text-end><?=$detalhe->estoque?>
        <td class=text-end><?=$total?>
        <td><?=$hist->hist?>
<?php endforeach; ?>
</table>

 

Editado por Frank K Hosaka
Link para o comentário
Compartilhar em outros sites

2 respostass a esta questão

Posts Recomendados

  • 0

Olá, @Frank K Hosaka!

Seu código já está bem estruturado, e o uso do Copilot para otimizar a rotina faz bastante sentido, principalmente ao reduzir a quantidade de processamento dentro do foreach(). No entanto, há algumas otimizações que podem melhorar o desempenho e evitar múltiplas consultas desnecessárias dentro do loop.


Sugestões para Melhorar a Performance

📌 1. Reduzir o Número de Queries dentro do Loop
No seu código, a cada iteração do foreach(), você executa três queries individuais (tbprod, tbdiario e tbhistprod). Isso pode ser um grande gargalo, especialmente se houver muitos produtos.

Solução: Busque todas as informações necessárias antes do loop, armazenando-as em arrays associativos.

📌 2. Utilizar GROUP BY e MAX() para Evitar o Processamento Manual
Ao invés de percorrer os registros manualmente para encontrar a última entrada de cada produto, você pode delegar isso ao MySQL, reduzindo o processamento no PHP.

Aqui está uma abordagem que pode ajudar:

 
php
CopiarEditar
$pdo = new PDO("mysql:host=localhost;dbname=teste", "root", ""); // Define intervalo de datas $inicio = '2024-10-01'; $fim = '2024-10-31'; // Consulta SQL otimizada $sql = "SELECT hp.* FROM tbhistprod hp INNER JOIN ( SELECT codprod, MAX(dia) as ult_dia FROM tbhistprod WHERE custototal > 0 AND dia BETWEEN '$inicio' AND '$fim' GROUP BY codprod ) as ult ON hp.codprod = ult.codprod AND hp.dia = ult.ult_dia ORDER BY hp.dia DESC"; $ultimo = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC); // Buscar detalhes dos produtos em um único SELECT $produtos = []; $historia = []; $totalEstoque = []; $ids = array_column($ultimo, 'codprod'); $idsStr = implode(',', array_map('intval', $ids)); if (!empty($ids)) { // Busca detalhes dos produtos de uma vez só $produtos = $pdo->query("SELECT * FROM tbprod WHERE codprod IN ($idsStr)") ->fetchAll(PDO::FETCH_UNIQUE | PDO::FETCH_OBJ); // Busca histórico de lançamentos de uma vez só $historia = $pdo->query("SELECT * FROM tbdiario WHERE lcto IN (SELECT DISTINCT lcto FROM tbhistprod WHERE codprod IN ($idsStr))") ->fetchAll(PDO::FETCH_UNIQUE | PDO::FETCH_OBJ); // Busca soma total dos custos de estoque de uma vez só $totalEstoque = $pdo->query("SELECT codprod, SUM(custototal) as soma FROM tbhistprod WHERE codprod IN ($idsStr) GROUP BY codprod") ->fetchAll(PDO::FETCH_UNIQUE | PDO::FETCH_OBJ); } ?>

Principais Melhorias nessa Abordagem

Diminuição drástica do número de queries dentro do loop, reduzindo o tempo de execução.
O uso de GROUP BY e MAX() no MySQL já retorna a última entrada de cada produto, eliminando a necessidade de fazer isso manualmente no PHP.
Consulta única para buscar todos os detalhes dos produtos e históricos, evitando múltiplas requisições ao banco.

Caso o seu projeto envolva gestão de estoque e vendas de forma mais automatizada, pode valer a pena considerar um sistema especializado para controle de produtos, como essa solução de gestão para varejo, que já integra funcionalidades avançadas sem necessidade de otimizações manuais.

Se precisar de mais ajustes ou explicações, estou por aqui! 🚀😊

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,4k
    • Posts
      652,2k
×
×
  • Criar Novo...