Ir para conteúdo

POWERED BY:

Arquivado

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

Fabio Mazucato

Consulta em 2 tabelas mysql

Recommended Posts

Fala galera mais uma vez estou aqui pra pedir um help.

 

Bom dessa vez eu vim pedir ajuda para melhorar, fiz um filtro para busca aqui da empresa

onde os operadores fazem um filtro para trazer apenas os clientes que lhes interessa.

 

No filtro eu tenho as seguintes opções:

 

BANCO

PAERCENTUAL DE PARCELAS PAGAS

ORGÃO DO CLIENTE

O OPERADOR DESSE CLIENTE

A DATA DE NASCIMENTO E UMA OPÇÃO PARA BASE DESSA IDADE (MAIOR QUE OU MENOR QUE)

 

Usei varios if's pq não é obrigatorio que o operador selecione as opções.

Ele pode apenas escolher o banco e o percentual de parcelas pagas, ai tive a idéia de fazer dessa forma

pq caso alguma campo fosse enviado sem valor não teria problemas na consulta.

 

Esta funcionando direito, só que demora MUITOOOOOOOOOOOOOOOOOOOOOOO

quero pedir ajuda aos que possam me ajudar, a fazer uma consulta melhor.

 

Lembrando que eu faço a consulta em 2 tabelas, CADASTRO e LANCAMENTOS.

 

if ($_POST["discriminacao"] == "0"){
		$vl1 = "";
		}else{
		$vl1 = " AND discriminacao='".$_POST["discriminacao"]."'";
		}
		
		if ($_POST["operador"] == "0"){
		$vl2 = "";
		}else{
		$vl2 = " AND operador='".$_POST["operador"]."'";
		}
		
		if ($_POST["porcent"] == ""){
		$vl3 = "";
		}else{
		$vl3 = " AND (parcela >= prazo * ".$_POST["porcent"]."/100)";
		}
		
		if ($_POST["orgao"] == "0"){
		$vl4 = "";
		}else{
		$vl4 = " AND orgao='".$_POST["orgao"]."'";
		}
		
		if ($_POST["nascimento"] == ""){
		$vl5 = "";
		}else{
		$vl5 = " AND nascimento ".$_POST["nasc"]."=".$_POST["nascimento"]."";
		}

        $sql ="SELECT * FROM cadastro INNER JOIN lancamentos ON cadastro.cpf = lancamentos.cpf WHERE 1=1 $v15 $vl1 $vl2 $vl4 $vl3 ORDER BY cadastro.servidor ASC";

Desde já agradeço a todos que puderem me ajudar

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você tem certeza que está demorando por causa disso????

 

Bom, mas vou tentar ajudar...

 

Primeiramente, tente não fazer assim:

 

$sql ="SELECT * FROM cadastro INNER JOIN lancamentos ON cadastro.cpf = lancamentos.cpf WHERE 1=1 $v15 $vl1 $vl2 $vl4 $vl3 ORDER BY cadastro.servidor ASC";

Faça assim:

 

$sql = "SELECT cadastro.cpf, lancamentos.campo1, lancamentos.campo2, lancamentos.campo3, lancamentos.etc FROM cadastro INNER JOIN lancamentos ON cadastro.cpf = lancamentos.cpf WHERE 1=1 ".$v15." ".$vl1." ".$vl2." ".$vl4." ".$vl3." ORDER BY cadastro.servidor ASC";

 

Assim você estará dando uma mãozinha para o PHP e também para o MySQL. Viu que eu estou dizendo quais campos quero que ele traga? E também como estou concatenando as variaveis ali?

 

Veja quais campos são necessários para retornar, se não for útil.. não precisa pedir no select.

Compartilhar este post


Link para o post
Compartilhar em outros sites

bOM NÃO CONSEGUIR NÃO.

 

Esse é o erro que da na minha execução do $sql na minha query:

 

Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /var/www/lyrus/busca_filtro.php on line 158

 

 

Meu cod:

$sql ="SELECT cadastro.cpf, cadastro.discriminacao, cadastro.servidor, cadastro.orgao, cadastro.nascimento, lancamentos.prazo, lancamentos.parcela, lancamentos.cpf FROM cadastro LEFT JOIN lancamentos ON cadastro.cpf = lancamentos.cpf WHERE $v15 $vl1 $vl2 $vl4 $vl3 ORDER BY cadastro.servidor ASC";

Compartilhar este post


Link para o post
Compartilhar em outros sites

o erro nao eh nessa linha

poste as linhas antes e depois desse Select

principalmente onde você tem o comando

 

mysql_num_rows();

 

boa

Compartilhar este post


Link para o post
Compartilhar em outros sites

O problema provavelmente é na consulta mesmo, porque está dizendo que o que foi enviado para o mysql_num_rows é inválido. Adicione na sua consulta, na posição que você utiliza o mysql_query() um or die(mysql_error()). Veja qual erro vai exibir.

 

Carlos Eduardo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Esta funcionando direito, só que demora MUITOOOOOOOOOOOOOOOOOOOOOOO

quero pedir ajuda aos que possam me ajudar, a fazer uma consulta melhor.

 

Se está funcionando, você deve deixar exatamente como estava antes porque o problema não está mais no PHP e sim no MySQL.

 

Sempre que você for fazer uma consulta você deve ter um índice adequado, caso contrário você causará um full scan.

 

Consultas full-scan são aquelas em que o banco de dados precisa fazer uma comparação linha por linha em todos os registros até encontrar o registro que atenda a condição imposta, por exemplo:

 

mysql> create table `pessoas` (
 -> `id` mediumint(8) unsigned not null auto_increment,
 -> `nome` varchar(50) not null,
 -> primary key(`id`)
 -> );
Query OK, 0 rows affected (0.00 sec)

mysql> insert into `pessoas`(`nome`) values('Matias'),('Rezende'),('Dee'),('Fabio'),('Mazucato'),('lucas'),('martins'),('Joao'),('Batista'),('Neto');
Query OK, 10 rows affected (0.00 sec)
Records: 10 Duplicates: 0 Warnings: 0

Como pode ver, criei uma tabela chamada pessoas e nela um campo nome sem índice e inseri 10 linhas.

 

Se eu precisar fazer uma consulta pelo nome:

mysql> select * from `pessoas` where `nome`='Neto';
+----+------+
| id | nome |
+----+------+
| 10 | Neto |
+----+------+
1 row in set (0.00 sec)

Aparentemente está tudo ok, mas olha o que aconteceu em background:

mysql> explain select * from `pessoas` where `nome`='Neto';
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | pessoas | ALL | NULL | NULL | NULL | NULL | 10 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

Observe na coluna rows que foi necessário fazer 10 comparações para me devolver o resultado que eu precisava, agora vamos criar um índice para a coluna nome:

 

mysql> alter table `teste`.`pessoas` add key `pessoas`(`nome`);
Query OK, 10 rows affected (0.05 sec)
Records: 10 Duplicates: 0 Warnings: 0

Agora o explain para a mesma consulta:

mysql> explain select * from `pessoas` where `nome`='Neto';
+----+-------------+---------+------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+---------+---------+-------+------+-------------+
| 1 | SIMPLE | pessoas | ref | pessoas | pessoas | 52 | const | 1 | Using where |
+----+-------------+---------+------+---------------+---------+---------+-------+------+-------------+
1 row in set (0.00 sec)

Veja que agora, a coluna rows mostra apenas 1, isso significa que foi necessário apenas uma comparação para retornar o resultado que eu precisava.

O grande ponto dos índices é que se tiver a possibilidade de se ter uma consulta usando a coluna nome com uma outra coluna qualquer e outra hora você usar só a outra coluna e outra apenas a coluna nome você terá que criar seus índices pensando nisso.

 

Se valer minha opinião, se seu PHP estava funcionando, deixe-o como estava e trabalhe agora para melhorar as consultas e criar os índices adequados para elas.

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim, se ele não criou os índices, provavelmente seja por isso... não tenha dúvida...

 

Mas a forma como ele ta concatenando e fazendo o select, com certeza irá interferir na performance do script.

 

Não se faz select com o "*" ... isso faz com que campos desnecessários sejam buscados no banco... podendo deixar lento a consulta... quando mais minimizado é a consulta, melhor... e com índices melhor ainda...

 

Abraçs

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não se faz select com o "*" ... isso faz com que campos desnecessários sejam buscados no banco... podendo deixar lento a consulta... quando mais minimizado é a consulta, melhor... e com índices melhor ainda...

 

Não vou discutir que se deve sempre minimizar os campos de uma consulta, porém imagine que você tenha a seguinte tabela:

Imagem Postada

 

Se você precisar listar todos os produtos (sem paginação) exibindo apenas o nome e o preço, a melhor consulta seria:

select `id`,`nome`,`preco` from `produtos` order by `nome`;

 

Dessa forma, criamos uma lista de produtos onde o usuário poderá clicar em um link e exibir o produto para efetuar uma possível compra:

 

<a href="/produtos/?id=1" title="Clique para ver o produto">Produto Qualquer</a>
<span class="preco">R$ 6,66</span>

 

Como pode ver utilizamos na listagem apenas os campos id, nome e preco, agora, quando o usuário clicar nesse link será mostrado também a descrição do produto, dessa forma, a melhor consulta será:

 

select * from `produtos` where `id`=1;

 

Isso porque agora precisamos de todos os dados do produto:

<h2>Produto Qualquer</h2>
<img src="/imagens/produtos?id=1" alt="produto" title="Produto Qualquer" />
<span class="descricao">Essa é a descrição do produto, bla bla bla</span>
<form action="/carrinho/add?id=1" method="post">
<fieldset>
<label for="p1">
<span>Quantidade</span>
<input id="p1" type="text" size="3" name="quantidade" />
</label>
<input id="bte" type="submit" value="Enviar" />
</fieldset>
</form>

 

O uso o * deve ser utilizado somente quando necessário e não totalmente evitado, existem casos em que ele deve ser utilizado e casos em que ele deve ser evitado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fala galera, esta semana estive meio ausênte aqui no trabalho, e voltei hoje.

 

Tendo apenas como suloção para esse problemas 2 formas.

 

1º, fazer esse filtro funcionar sem demora

2º, mudar para asp, e ulitizar o SQL SERVER, pq no SQL SERVER, faz uma consulta VIEW, ele faz um

exemplo desta consulta, e deixa guardada como se fosse uma tabela. Ou seja sempre que essa consulta for

feita o SQL SERVER terá sempre a VIEW para essa consulta arquivada, resultando otimo desempenho na busca.

 

Prefiro não mudar para ASP, alguem ai será que pode me dar um exemplo dessa minha consulta da forma correta

de se fazer?

 

Valeu desde já agradeço a todos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Dá para criar VIEW no MySQL tb.. isso se você tiver usando MySQL > 5.0

Compartilhar este post


Link para o post
Compartilhar em outros sites

O uso o * deve ser utilizado somente quando necessário e não totalmente evitado, existem casos em que ele deve ser utilizado e casos em que ele deve ser evitado.

 

Pois é, também depende muito da forma que o cara ta programando, se for bem procedural... ele terá que fazer select apenas daquilo que ele irá usar naquela página...

 

Agora se for OO, até pode-se utilizar do "*", porque não né? vamo cai pra dentro http://forum.imasters.com.br/public/style_emoticons/default/grin.gif.

 

Mas mesmo assim, para ter um maior controle e flexibilidade da minha consulta, eu, particularmente, prefiro chamar cada campo a utilizar o "*".

 

Mas ta valendo. Obrigado João!

 

Abraço meu amigo!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sobre como criar VIEW com Mysql.

http://dev.mysql.com/doc/refman/5.0/en/create-view.html

 

Se quiser trabalhar com o PHP e o SQL Server também dá.

 

Carlos Eduardo

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

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