Ir para conteúdo

POWERED BY:

Arquivado

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

HelioCesar

Melhorar Desempenho da Consulta

Recommended Posts

Ola a todos, estou trabalhando com o phpmyadmin e fiz uma consulta que retorna os dados dos produtos por usuário, resumindo tenho 5 tabelas, produto, pedido, item_pedido, item_pedido_preco, e usuarios a minha consulta esta demorando em torno de 1 minuto para retornar queria ver se algem tem alguma ideia para melhorar o desempenho, ficar mais rapido, segue as informações de cada tabela.

 

tabela | quantidade de informações

pedido = 1

item_pedido = 350

usuarios = 9

item_pedido_preco = 3150

 

abaixo segue o sql, estou trabalhando com PHP.

private function itemprecofinalizado(){
  ini_set('max_execution_time','220');//estou aumenta o tempo de execucao pis a consulta esta muito lenta
  if($this->get_request_method() != "GET"){
	$this->response('',406);
   }
$id =(int)$this->_request['id'];
	if($id > 0){

//inicio conexao com o banco
            $DB_HOST = "localhost";
            $DB_NAME = "banco";
            $DB_PORTA = "3306";
            $DB_USER = "root";
            $DB_PASS = "root";

            $conexao = mysql_connect($DB_HOST,$DB_USER,$DB_PASS) or die ("Erro na Conexão!");
            $db = mysql_select_db($DB_NAME, $conexao) or die ("Erro na Conexão!");
//fim conexao com o banco

            //PEGA TODOS OS ITENS REFERENTE AO PEDIDO
            $sqlProduto = mysql_query("SELECT * FROM item_pedido i INNER JOIN produto p ON i.id_pedido = '".$id."' AND i.id_produto = p.prod_id ORDER BY p.prod_descricao") or die (mysql_error());
            $quantProduto = mysql_num_rows($sqlProduto);
            if($quantProduto > 0 ){
                while($rowItem = mysql_fetch_array($sqlProduto)){
                    $duplicidade = 0;//verifica preco em duplicidade

                    $id_pedido          = $rowItem['id_pedido'];
                    $id_prod		    = $rowItem['id_produto'];
                    $prod_qtd		    = $rowItem['item_qtd'];
                    $prod_descricao	    = $rowItem['prod_descricao'];
                    $prod_unidade	    = $rowItem['prod_unidade'];
                    $prod_embalagem	    = $rowItem['prod_embalagem'];

//INICIO essa parte so pega o menor preco de cada item na tabela item_pedido_preco para depois fazer a comparacao
                    $sqlMenor = mysql_query("SELECT min(item_vl_imposto) FROM item_pedido_preco r WHERE r.id_pedido ='".$id."' AND r.id_produto ='".$id_prod."' and r.item_vl_imposto != 0") or die (mysql_error());
                    $rowMenor = mysql_fetch_assoc($sqlMenor);
                    $menor = str_replace('.',',', $rowMenor['min(item_vl_imposto)']);
//FIM MENOR VALOR

//INICIO BUSCA TODOS OS USUARIOS DA TABELA E EM CADA UM DELES COLOCA TODOS OS ITENS, MESMO OS QUE ELES NAO COTAO
                    $sqlUsuario = mysql_query("SELECT * FROM usuarios WHERE usu_nivel = 1 and usu_status = 1 ORDER BY usu_id") or die (mysql_error());
                    $quantUsuario = mysql_num_rows($sqlUsuario);
                    if($quantUsuario > 0){
                        while($rowUsu = mysql_fetch_array($sqlUsuario)){
                            $usu_id = $rowUsu['usu_id'];

//INICIO PRODUTO, USUARIO, E PEGAR OS PRECOS DE TODOS OS ITENS CONFORME INFORMACAO ACIMA
                            $sqlPreco = mysql_query("SELECT * FROM item_pedido_preco WHERE id_pedido ='".$id."' AND id_produto ='".$id_prod."' AND id_usuario= '".$usu_id."' ORDER BY id_usuario") or die (mysql_error());
                            $quantPreco = mysql_num_rows($sqlPreco);
                            if($quantPreco > 0){
                                while($rowPreco = mysql_fetch_array($sqlPreco)) {

                                    $id_usuario		    = $rowUsu['usu_id'];
                                    $item_vl_anterior   = str_replace('.',',',$rowPreco['item_vl_imposto']);
                                    $item_vl_imposto    = str_replace('.',',',$rowPreco['item_vl_imposto']);
                                    $usu_titulo		    = $rowUsu['usu_titulo'];
                                    $usu_imposto        = $rowUsu['usu_imposto'];

                                    if($rowPreco['item_vl_unit'] == 0 or $rowPreco['item_vl_unit'] == NULL):
                                        $resultproduto[] = array(
                                            'id_usuario' => $id_usuario,
                                            'item_vl_imposto' => "-",
                                            'item_vl_anterior' => "-",
                                            'usu_titulo' => $usu_titulo,
                                            'usu_imposto' => $usu_imposto
                                        );
                                    else:
                                        $resultproduto[] = array(
                                            'id_usuario' => $id_usuario,
                                            'item_vl_imposto' => $item_vl_imposto,
                                            'item_vl_anterior' => $item_vl_anterior,
                                            'usu_titulo' => $usu_titulo,
                                            'usu_imposto' => $usu_imposto
                                        );
                                        if($item_vl_imposto == $menor):
                                            $duplicidade = $duplicidade+1;
                                        endif;
                                    endif;
                                }//while item_preco
                            }else{//se nao tiver no item_preco
                                $id_usuario		    = $usu_id;
                                $item_vl_anterior   = "NULL";
                                $item_vl_imposto    = "NULL";
                                $usu_titulo		    = $rowUsu['usu_titulo'];
                                $usu_imposto        = $rowUsu['usu_imposto'];

                                $resultproduto[] = array(
                                    'id_usuario' => $id_usuario,
                                    'item_vl_imposto' => $item_vl_imposto,
                                    'item_vl_anterior' => $item_vl_anterior,
                                    'usu_titulo' => $usu_titulo,
                                    'usu_imposto' => $usu_imposto
                                );
                            }//FIM
                        }//while usuario
                    }
                    //FIM
                    if($duplicidade > 1)://informa qual item esta com preco em duplicidade
                        $prod_repeat = '*';
                    else:
                        $prod_repeat = '';
                    endif;

                    $result[] = array(
                        'id_pedido' => $id_pedido,
                        'id_produto' => $id_prod,
                        'prod_qtd' => $prod_qtd,
                        'prod_descricao' => $prod_descricao,
                        'prod_unidade' => $prod_unidade,
                        'prod_embalagem' => $prod_embalagem,
                        'item_vl_unit' => $resultproduto,
                        'itemmenorpreco' => $menor,
                        'prod_repeat' => $prod_repeat
                    );
                    $resultproduto = "";
                }//while item_pedido
                $this->response($this->json($result), 200);
            }
            $this->response('',204);
        }
}

segue abaixo a imgem com o retorno da consulta.

telafinalizado.png

 

 

Grato pela ajuda

Compartilhar este post


Link para o post
Compartilhar em outros sites

São várias consulta e não apenas uma q vc está rodando no seu bacalhau.

 

O ideal é que você rode as consultas diretamente no banco e veja quais estão realmente demorando (no seu ponto de vista do q é lento acima do q deveria) e então aplicar um EXPLAIN na frente e postar aqui para que possamos analisar. Ex.:

Select * from tabela_a a, tabela_b b where a.id = b.id;

vira

EXPLAIN Select * from tabela_a a, tabela_b b where a.id = b.id;

Também é ideal que vc poste as estruturas das tabelas com SHOW CREATE TABLE

 

Ex.:

Show create table tabela_a;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ola giesta, desculpe a demora para responder estava viajando, mais vamos la, segue abaixo a estrutura que você pediu.

 

tabela item_pedido: onde fica todos os itens que foi digitado

CREATE TABLE `item_pedido` (
 `id_pedido` int(5) DEFAULT NULL,
 `id_produto` int(5) DEFAULT NULL,
 `item_sequencia` int(5) DEFAULT NULL,
 `item_obs` varchar(100) DEFAULT NULL,
 `item_qtd` int(5) DEFAULT NULL,
 `item_status` varchar(1) DEFAULT NULL,
 `item_tipo` varchar(1) NOT NULL,
 KEY `id_pedido` (`id_pedido`),
 KEY `id_produto` (`id_produto`),
 CONSTRAINT `item_pedido_ibfk_1` FOREIGN KEY (`id_pedido`) REFERENCES `pedido` (`ped_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
 CONSTRAINT `item_pedido_ibfk_2` FOREIGN KEY (`id_produto`) REFERENCES `produto` (`prod_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8

tabela produto: somente para pegar o complemento dos dados do produto

CREATE TABLE `produto` (
 `prod_id` int(5) NOT NULL AUTO_INCREMENT,
 `prod_descricao` varchar(100) NOT NULL,
 `prod_unidade` varchar(2) NOT NULL,
 `prod_embalagem` varchar(8) NOT NULL,
 `prod_datacadastro` date DEFAULT NULL,
 `prod_status` varchar(1) NOT NULL,
 `prod_tipo` varchar(1) NOT NULL,
 PRIMARY KEY (`prod_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6507 DEFAULT CHARSET=utf8

tabela item_pedido_preco: onde fica somente os preços dos produtos.

CREATE TABLE `item_pedido_preco` (
 `id_usuario` int(5) DEFAULT NULL,
 `id_pedido` int(5) DEFAULT NULL,
 `id_produto` int(5) DEFAULT NULL,
 `item_vl_unit` decimal(10,2) DEFAULT NULL,
 `item_vl_imposto` decimal(10,2) DEFAULT NULL,
 KEY `pedido_fk` (`id_pedido`),
 KEY `produto_fk` (`id_produto`),
 KEY `usuario_fk` (`id_usuario`),
 CONSTRAINT `item_pedido_preco_ibfk_1` FOREIGN KEY (`id_usuario`) REFERENCES `usuarios` (`usu_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
 CONSTRAINT `item_pedido_preco_ibfk_2` FOREIGN KEY (`id_pedido`) REFERENCES `pedido` (`ped_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
 CONSTRAINT `item_pedido_preco_ibfk_3` FOREIGN KEY (`id_produto`) REFERENCES `produto` (`prod_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
 CONSTRAINT `item_pedido_preco_ibfk_4` FOREIGN KEY (`id_usuario`) REFERENCES `usuarios` (`usu_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
 CONSTRAINT `item_pedido_preco_ibfk_5` FOREIGN KEY (`id_pedido`) REFERENCES `pedido` (`ped_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
 CONSTRAINT `item_pedido_preco_ibfk_6` FOREIGN KEY (`id_produto`) REFERENCES `produto` (`prod_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8

tabela usuarios: onde fica todos os usuarios que participa das cotações

CREATE TABLE `usuarios` (
 `usu_id` int(5) NOT NULL AUTO_INCREMENT,
 `usu_nome` varchar(100) NOT NULL,
 `usu_empresa` varchar(100) NOT NULL,
 `usu_email` varchar(50) NOT NULL,
 `usu_titulo` varchar(8) NOT NULL,
 `usu_senha` varchar(100) NOT NULL,
 `usu_nivel` int(2) NOT NULL,
 `usu_status` int(1) NOT NULL,
 `usu_imposto` decimal(4,2) NOT NULL,
 `USU_TipoCotacao` char(1) NOT NULL,
 `USU_OnOff` int(1) NOT NULL,
 `USU_ContaAcesso` int(5) NOT NULL,
 PRIMARY KEY (`usu_id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8

com relação ao EXPLAIN veja se é isso que você esta querendo dizer!

Query SQL: EXPLAIN SELECT * FROM item_pedido i INNER JOIN produto p WHERE i.id_pedido = 83 AND i.id_produto = p.prod_id ORDER BY p.prod_descricao;
Registros: 2
id 	select_type 	table 	type 	possible_keys 	         key 	       key_len 	ref 	                      rows 	Extra
1 	SIMPLE 	          i 	ref 	id_pedido,id_produto 	id_pedido 	5 	const 	                      260 	Using where; Using temporary; Using filesort
1 	SIMPLE 	          p 	eq_ref 	PRIMARY 	        PRIMARY 	4 	supermercado.i.id_produto      1 	NULL
Query SQL: EXPLAIN SELECT * FROM usuarios WHERE usu_nivel = 1 and usu_status = 1 ORDER BY usu_id;
Registros: 1
id 	select_type 	table 	type 	possible_keys 	key 	key_len 	ref 	rows 	Extra
1 	SIMPLE 	usuarios 	index 	NULL	      PRIMARY 	   4 	        NULL	16 	Using where

tem outras consultas que não tem como eu fazer assim, pois precisa do ID de varios itens.

 

grato pela ajuda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por ILR master
      Boa tarde, pessoal.
      Espero que todos estejam bem.
       
      Seguinte:
      Tenho a seguinte consulta:
       
      $usuarios= "SELECT * FROM usuarios";
      $query= mysqli_query($conexao, $usuarios) or die ("Usuário não encontrado");
      $usuario = mysqli_fetch_array($query);
       
      Quero pegar apenas o campo 'nome' da tabela 'usuarios' e colocar todos os resultados da seguinte forma:
       
      $nomes = array("Rafael", "João", "Maria", "Pedro", "Patricia", "Camila");
       
      Agradeço desde já.
      Abs
       
       
    • Por FabianoSouza
      Tenho uma function que precisa receber 02 argumentos.
      Ela funciona se eu aplicar num select qualquer. Mas se eu aplicar num select dinâmico, ocorre erro.
      Veja trecho do meu select.
      ... SET @sql = @sql +', dbo.retornaIco_ItemBloq((SELECT COUNT(*) FROM dbo.tab AS TT2 WHERE TT2.codCategTreina = CTT.id),'+@title+') AS ''resp''' ... No caso, o primeiro argumento da function dbo.retornaIco_ItemBloq é um SELECT COUNT.
      O segundo argumento é uma variável (que está devidamente declarada e definida).
       
      O erro ocorre porque ao executar (chamando EXEC(@sql) ), o SQL entende que o segundo argumento é uma coluna da consulta principal, pois existe uma vírgula antes da variável @title (que é o segundo argumento da function).
      Repito. Se eu aplicar essa function num select normal, funciona normalmente. Porém, preciso que funcione num SQL dinâmico porque é esse é o padrão que estou adotando para o sistema todo.
       
      A function dbo.retornaIco_ItemBloq faz o seguinte:
      1) Recebe o valor do COUNT e da variável @title
      2) Se o COUNT for maior que  Zero, cria uma tag HTML (uma SPAN), define sua title com o valor da variável @title e passa para uma variável
      3) Retorna o HTML que será exibido no resultado da consulta principal
      É super simples.
       
      Há outra forma de chamar a function?
    • Por mr22robot
      Ola caros amigos. 
      Estou com uma dúvida aqui que embora nao tenho achado ainda uma resposta, acredito que haja.
      Estou estudando a tão sonhada linguagem de programação asp.net core mvc. Linguagem essa que demorei 5 anos pra iniciar os estudos rsrs.
      Mas estou agarrado em uma situação. 
      Estou usando como base de dados nos meus estudos um banco Oracle. Que já tem algumas informações nele. Utilizei o SCAFFOLD para criar as classes e o contexto baseado no banco e tabelas existentes. 
      Porem agora na fase das consultas, estou perdido em como utilizar o IN que eu utilizo no oracle; no LINQ.
      Ex: 
      SELECT CODPROD,DESCRICAO FROM PRODUTO WHERE CODPROD IN(1,2,3,4,5,6) Como eu utilizo esse filtro com uma restrição de códigos de produtos? no caso o where codprod in(1,2,3,4,5,6) ?.
      Desde já obrigado pela ajuda.
    • Por Sapinn
      Olá a todos existe alguma maneira de trazer todos os dados de uma tabela menos o maior valor?
    • Por Wandersonwfs
      Bom dia Pessoal,
       
      Estou com um problema para finalizar uma consulta onde, quando executado a consulta  e não encontrado nenhuma informação no período solicitado, tenho que trazer pelo menos o nome da conta.
       
      Consulta,
       
      WITH TMPESTONO (
          NOME_IMPOSTO
          ,MES
          ,VALOR
          )
      AS (
          SELECT 'ESTORNO SOBRE GREEN VILLE' AS NOME_IMPOSTO
              ,'F_' + SZN.ZN_ITEM AS FILFOR
              ,SUM((SZN.ZN_PRV * SZN.ZN_PRCAPL) / 100) AS TOTAL
          FROM SZN010 SZN
          WHERE SZN.D_E_L_E_T_ = ' '
              AND SZN.ZN_ITEM IN (
                  '01'
                  ,'16'
                  ,'30'
                  ,'40'
                  ,'46'
                  ,'51'
                  ,'52'
                  ,'60'
                  ,'70'
                  ,'72'
                  ,'73'
                  ,'80'
                  )
              AND SZN.ZN_DATA BETWEEN '20220701'
                  AND '20220731'
              AND SZN.ZN_DESC = ('GRENVILLE')
          GROUP BY SZN.ZN_DESC
              ,SZN.ZN_ITEM
          )
      SELECT *
      FROM (
          SELECT NOME_IMPOSTO
              ,MES
              ,VALOR
          FROM TMPESTONO
          ) AS PivotData
      PIVOT(SUM(VALOR) FOR MES IN (
                  [F_16]
                  ,[F_30]
                  ,[F_40]
                  ,[F_46]
                  ,[F_51]
                  ,[F_52]
                  ,[F_60]
                  ,[F_70]
                  ,[F_72]
                  ,[F_73]
                  ,[TOTAL]
                  )) AS PivotTable2
      ORDER BY 1
       
×

Informação importante

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