leooizepi 1 Denunciar post Postado Agosto 16, 2012 Bom dia galera, Estou com um problema de uma query que esta demorando 26s. Vou explicar como é a estrutura (resumida) da base da dados. pedido ============= id nome_cliente valor pedido_atributo_valor ===================== id_pedido id_atributo id_valor atributo =============== id nome_atributo Na tabela "pedido", temos um registro para cada pedido realizado (tranquilo por aqui). Na tabela "atributo", temos x tipos de atributos, por exemplo (cpf, rg, agencia, conta, etc). E na tabela "pedido_atributo_valor", temos os valores inseridos do pedido. O problema é que se eu fizer uma consulta para saber todos os valores de um determinado pedido, esse pedido vai me retornar 1 linha para cada atributo. Qual seria a maneira mais otimizada de realizar essa consulta para retornar em cada linha, todos os meu atributos e valores do pedido? Valeu, obrigado! Compartilhar este post Link para o post Compartilhar em outros sites
Prog 183 Denunciar post Postado Agosto 16, 2012 select p.nome_cliente, p.valor, a.nome_atributo, pa.id_valor from pedido_atributo_valor pa join pedido p on p.id=pa.pedido_id join atributo a on a.id=pa.atribudo_id Isso não atende? Compartilhar este post Link para o post Compartilhar em outros sites
leooizepi 1 Denunciar post Postado Agosto 16, 2012 Se houver 3 atributos, cada registro do pedido vai me retornar 3 linhas. Colocando o numero do pedido nessa SQL, vai ficar assim por exemplo: atributos: cpf, agencia e conta. o retorno dessa sql seria mais ou menos isso: id_pedido | nome_cliente | valor | nome_atributo | id_valor ----------------------------------------------------------- 1 | cliente 1 | 10 | cpf | 111.111.111-11 1 | cliente 1 | 10 | agencia | 0123 1 | cliente 1 | 10 | conta | 1234567 2 | cliente 2 | 20 | cpf | 222.222.222-22 2 | cliente 2 | 20 | agencia | 0888 2 | cliente 2 | 20 | conta | 999999999 Detalhe importante: Eu já sei quais atributos eu irei ter na SQL, não é para listar todos, vamos definir nesse exemplo então que os campos da SQL seriam ID_PEDIDO, NOME_CLIENTE, VALOR, AGENCIA e CONTA. Eu preciso que cada pedido retornasse em apenas 1 linha com os atributos pré selecionados. Onde ficaria: id_pedido | nome_cliente | valor | agencia | conta ------------------------------------------------------ 1 | cliente 1 | 10 | 0123 | 1234567 2 | cliente 2 | 20 | 0888 | 999999999 valeu, obrigado! Compartilhar este post Link para o post Compartilhar em outros sites
Prog 183 Denunciar post Postado Agosto 16, 2012 Tente isso: select p.nome_cliente, p.valor, group_concat(pa.id_valor) from pedido_atributo_valor pa join pedido p on p.id=pa.pedido_id join atributo a on a.id=pa.atribudo_id where a.nome_atributo in ('AGENCIA','CONTA') group by p.nome_cliente, p.valor select p.id, p.nome_cliente, p.valor, group_concat(pa.id_valor ORDER BY a.nome_atributo ASC) from pedido_atributo_valor pa join pedido p on p.id=pa.pedido_id join atributo a on a.id=pa.atribudo_id where a.nome_atributo in ('AGENCIA','CONTA') group by p.id, p.nome_cliente, p.valor Fiz algumas alterações. Compartilhar este post Link para o post Compartilhar em outros sites
leooizepi 1 Denunciar post Postado Agosto 16, 2012 Eu queria acessar o atributo como se fosse uma coluna normal. SELECT '' as ID_PEDIDO, '' as NOME_CLIENTE, '' as VALOR, '' as AGENCIA '' as CONTA FROM ... Teria como realizar dessa maneira? Eu consegui fazer realizando sub-query para cada atributo, mas ficou muito lento. Valeu. Compartilhar este post Link para o post Compartilhar em outros sites
Prog 183 Denunciar post Postado Agosto 16, 2012 Hmmmm... Tente isto. select pa.id_pedido, p.nome_cliente, p.valor, substring_index(group_concat(pa.id_valor ORDER BY a.nome_atributo ASC SEPARATOR '#'), '#', 1) as agencia, substring_index(group_concat(pa.id_valor ORDER BY a.nome_atributo ASC SEPARATOR '#'), '#', -1) as conta from pedido_atributo_valor pa join pedido p on p.id=pa.pedido_id join atributo a on a.id=pa.atribudo_id where a.nome_atributo in ('AGENCIA','CONTA') group by pa.id_pedido, p.nome_cliente, p.valor Compartilhar este post Link para o post Compartilhar em outros sites
leooizepi 1 Denunciar post Postado Agosto 16, 2012 É isso ae Prog, vai funcionar. Em questão de desempenho, essa também seria a melhor alternativa? Parabéns! valeu, muito obrigado. Compartilhar este post Link para o post Compartilhar em outros sites
Prog 183 Denunciar post Postado Agosto 16, 2012 Em questão de desempenho, outras coisas precisam ser analisadas, como os indices criados. Você esta usando FKs? Tabelas InnoDB ou MyISAM? Compartilhar este post Link para o post Compartilhar em outros sites
leooizepi 1 Denunciar post Postado Agosto 16, 2012 Sim, estou usando FKs e tabelas InnoDB. Compartilhar este post Link para o post Compartilhar em outros sites
Prog 183 Denunciar post Postado Agosto 16, 2012 Em quanto tempo a query esta executando? Compartilhar este post Link para o post Compartilhar em outros sites
leooizepi 1 Denunciar post Postado Agosto 16, 2012 Para apenas 1 pedido, esta em 9 segundos, nessa mesma estrutura de SQL que fizemos. A tabela de pedidos, esta em 12 mil registros. Cada pedido tem uns 30 atributos, e a tabela que salva os valores esta em 400mil registros. Compartilhar este post Link para o post Compartilhar em outros sites
Bruno Augusto 417 Denunciar post Postado Agosto 16, 2012 Desculpa o comentário nada produtivo mas... Nove SEGUNDOS? Compartilhar este post Link para o post Compartilhar em outros sites
leooizepi 1 Denunciar post Postado Agosto 16, 2012 exato... hehe 9 segundos, isso para uma condição de where do codigo do pedido. para uma consulta de pedidos do mês (07/2012), esta demorando em torno de 4, 5min. valeu. Compartilhar este post Link para o post Compartilhar em outros sites
Prog 183 Denunciar post Postado Agosto 16, 2012 Você pode postar a estrutura das tabelas envolvidas, índices e as PKs? Compartilhar este post Link para o post Compartilhar em outros sites
leooizepi 1 Denunciar post Postado Agosto 21, 2012 Boa tarde Prog, Estou com o tempo curto, devido minha tarefas. Vou tentar colocar as tabelas e indices até na sexta feira. Valeu, obrigado! Compartilhar este post Link para o post Compartilhar em outros sites