Jump to content
lesilva

Melhoria na consulta

Recommended Posts

Então pessoal queria melhorar minha consulta deixar ele menor e se possível mais rápida.

 

Hoje está assim:

 

SELECT
    pn.OID,
    pn.NOME,
    pt.NOME_DO_TIPO,
    pt.TIPO,
    pf.CPF,
    pj.CGC,
    CASE
        WHEN pf.OID
        THEN 'FISICA'
        WHEN pj.OID
        THEN 'JURIDICA'
        ELSE ''
    END AS DESCRICAO
FROM
    pessoa pn
LEFT JOIN parte pt
ON
    pn.OID = pt.OID
    ------------------------------------
LEFT JOIN pessoa_fisica pf
ON
    pn.OID = pf.OID
    ----------------------------------
LEFT JOIN pessoa_juridica pj
ON
    pn.OID = pj.OID
    ---------------------------------
WHERE
    (
        (
            NOT EXISTS
            (
                SELECT
                    NULL
                FROM
                    advogado a
                WHERE
                    pn.OID = a.OID
            )
        )
    AND
        (
            NOT EXISTS
            (
                SELECT
                    NULL
                FROM
                    advogado_contrario ac
                WHERE
                    pn.OID = ac.OID
            )
        )
    AND pt.TIPO <= 1
    )
ORDER BY
    pn.NOME;

Share this post


Link to post
Share on other sites

Essa consulta e feita pontualmente então não tem índice, sobre o not exists  coloquei pois na tabela pessoa tem tudo e os mesmo não deve sair no relatório.

Queria saber se tem como melhora no sentido de não tem tantas cláusulas, tentar utilizar menos requisições. De repente na mesma condição conseguir realizar mais coisas, só que sou novo nesse parte da banco e não consigo diminuir.

 

Share this post


Link to post
Share on other sites

lesilva

Se isso for para gerar um relatório via aplicação, eu recomendo você a fazer as consultas de forma separadas.

Vale lembrar que quanto mais condições no WHERE desde que sejam campos como CHAVES e/ou INDICES melhor o desempenho.

 

Dúvida: Do jeito que está, a sua clausula traz exatamente o que você quer?

Pelos nomes das suas tabelas e como você esta amarrando, você procura em PESSOA e quer que ela esteja em PESSOA_FISICA e PESSOA_JURIDICA, é isso mesmo?

 

Como no seu caso existe uma regra de negócio, eu no seu caso faria assim:

 

Primeiro realizaria o SELECT na tabela para se obter os registros:

#Primeiro select

SELECT
    pessoa.OID,
    pessoa.NOME,
    parte.NOME_DO_TIPO,
    parte.TIPO,
    pessoaFisica.CpessoaFisica,
    pessoaJuridica.CGC,
    CASE
        WHEN pessoaFisica.OID
        THEN 'FISICA'
        WHEN pessoaJuridica.OID
        THEN 'JURIDICA'
        ELSE ''
    END AS DESCRICAO
FROM pessoa LEFT JOIN parte                                                ON pessoa.OID = parte.OID
                          LEFT JOIN pessoa_fisica pessoaFisica        ON pessoa.OID = pessoaFisica.OID

                          LEFT JOIN pessoa_juridica pessoaJuridica ON pessoa.OID = pessoaJuridica.OID

WHERE parte.TIPO <= 1
ORDER BY pessoa.NOME asc;

 

Para cada registro encontrado eu faria um acesso nas outras tabela passando o OID da tabela PESSOA limitanto a apenas 1 registro, se existir nas tabelas, então eu desprezo o registro, caso contrário eu movimento para o relatório.

 

#Segundo select

SELECT OID
  FROM advogado
 WHERE OID = "pessoa.OID" -- Para cada retorno do #Primeiro select  passa o OID para verificar se existe na tabela;

    LIMIT 1;

 

#Terceiro select

SELECT OID
  FROM advogado_contrario
 WHERE OID = "pessoa.OID" -- Para cada retorno do #Primeiro select  passa o OID para verificar se existe na tabela;

    LIMIT 1;

 

Desta forma na hora de gerar o relatório se for via aplicação (PHP, ASP, C, C#, Java, ou seja lá qual for a linguagem) o tempo de resposta será muito menor.

 

O melhor é você adicionar mais campos no seu WHERE como limite por data, por código, por tipo, etc... utilizar se possivel a maior quantidade de colunas chave da tabela, criar indice e evitar o uso de JOIN's, pois o processo dessa solicitação geralmente costuma ser bem onerosa para o banco de dados.

 

Eu estou na dúvida sobre o resultado da sua query, acho que você deveria apartar,

Primeiro um select

  • pessoa inner join parte
  • pessoa inner join pessoa_fisica
  • Para obter a lista de pessoa.pessoa_fisica
  • Verificar nas tabelas advogado advogado_contrario.
  • Se encontrar despreza, se não encontrar move saida

Segundo um select

  • pessoa inner join parte
  • pessoa inner join pessoa_juridica
  • Para obter a lista de pessoa.pessoa_juridica
  • Verificar nas tabelas advogadoadvogado_contrario.
  • Se encontrar despreza, se não encontrar move saida

Não seria isso?

 

Se a minha resposta for útil não esqueça de agradecer e votar positivo.

Espero ter ajudado de alguma forma.

 

Att
Felipe Guedes Coutinho

Share this post


Link to post
Share on other sites

Essa consulta é feita diretamente no banco, essas tabela são relacionadas pessoa contem praticamente todos dos dados, física pego somente o cpf, jurídica somente o CNJ e na parte pego o tipo se é física, jurídica, se é cliente, contrario entre outras opções de tipo.

Queria um forma de maximizar a consulta de repente fazer um maior numero de comparação dentro do CASE ou join e se possível retirar o NOT EXISTS.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By Murilo Corrêa
      Bom dia Senhores, 
       
      Estou com um dificuldade, onde precisava que minha consulta trouxesse apenas a menor data para cada produto. 
       
      Faço o cruzamento entre 3 tabelas. Segue 2 Selects que tentei, porém está trazendo todas as datas (termino_digitacao) de cada item.
       
      Tentativa 1: 
       
      select concat(prd.cod_produto, prd.digito) as Cod_Delage, prd.descricao as Descricao, p.termino_digitacao as Entrada, p.cod_pedido as Pedido from pedido p (NOLOCK) inner join pedido_item pedi (NOLOCK) on p.cod_pedido= pedi.cod_pedido inner join produto prd (NOLOCK) on pedi.cod_produto= prd.cod_produto where p.operacao=2 and p.termino_digitacao=(select Min(pe.termino_digitacao) FROM pedido pe WHERE pe.cod_pedido=p.cod_pedido GROUP BY cod_pedido) GROUP by prd.cod_produto,prd.digito, prd.descricao, p.termino_digitacao, p.cod_pedido ORDER BY Cod_Delage  
      Tentativa 2: 
       
      select concat(prd.cod_produto, prd.digito) as Cod_Delage, prd.descricao as Descricao, p.termino_digitacao as Entrada, p.cod_pedido as Pedido from (select cod_pedido, MIN(termino_digitacao) as entrada from pedido (NOLOCK) group by cod_pedido) pe inner join pedido p (NOLOCK) on pe.cod_pedido= p.cod_pedido and pe.cod_pedido=p.cod_pedido and pe.entrada= p.termino_digitacao inner join pedido_item pedi (NOLOCK) on p.cod_pedido= pedi.cod_pedido inner join produto prd (NOLOCK) on pedi.cod_produto= prd.cod_produto where p.operacao=2 GROUP by prd.cod_produto,prd.digito, prd.descricao, p.termino_digitacao, p.cod_pedido ORDER BY p.termino_digitacao asc
       
       
      OBS: Ambas estão trazendo as mesmas informações kkk. 
    • By gabyin
      estou fazendo uma lista de exercícios para a escola, mas não consigo resolver esse erro, alguém pode me ajudar?
       

    • By Salvatore
      Então, eu estou gravando uns dados no bancos de dados usando text area, mas quando eu dou espaço ou algo do tipo fica assim
       
      Ex :aaaa\r\naaaaaa\r\n
       
      onde esses \r\n são espaços e outras coisas, e ficam sendo exibidos quando eles retorna para a pagina
      alguém sabe como resolvo isso?
    • By drx
      Olá pessoal!
      Estou com um probleminha aqui. Estou me embrenhando pelos ajax e jquery. Muito interessante. 
      Eu peguei um exemplo e é bem simples. Só que não retorna a mensagem para a div.
       
      Eu tenho uma div em pagina1.php onde o usuário entra com um número identificador em um campo textfield.
      Após entrar com o número identificador, solicito a verificação em uma outra página.php onde tenho uma consulta no mysql.
      O echo da consulta é: Existente ou Inexistente. A consulta é feita pelo número identificador. Fiz a verificação e retorna perfeitamente,
      Porém eu quero que ao verificar, a mensagem retorne para minha outra div logo abaixo na pagina1.php
      Vou passar o código para facilitar....
       
      <html>
      <head>
       
      <script src="js/jquery.js"></script>
      <script>
      $(function(){
        $('#form').submit(function(){
           $.ajax({
             url: 'x_consultar_patro.php',
             type: 'POST',
             data: $('#form').serialize(),
             success:function ( data ) {
                 if (data != '') {
                     $('#frm_cadastro').html( data );
                 }
               }
             });
           return false;
         });
      });
      </script>
       
      </head>
       
      <body>

      <div id="frm_cadastro"></div>

      <form id="form" method="post" action="">
        <input type="text" name="codpatro" id="codpatro"/>
        <input type="submit" name="btn_procurar" id="btn_procurar" value="Procurar"/>
      </form>
       
      </body>
      <html>
       
       

    • By kelvinferraz
      Boa tarde Pessoal tudo bem?
       
      Estou criando uma aplicação basica para um usuario logar e acessar os dados dessa aplicação via um dashboard. 
       
      Surgiu uma dúvida, eu gostaria de publicar isso para que qualquer usuario possa acessar via web por exemplo: www.meusite.com/login
       
      A partir desse login defeniria qual base de dados esse usuário esta vinculado, por exemplo:
       
      O usuário acessa a area de login do site:
      Login: UsuarioX ------> Conecta ao db_usuariox
       
      Login:UsuarioY -------> Conecta ao db_usuarioy
       
      Como posso fazer isso?
       
      Estou aprendendo mais afundo PHP agora, então se puderem me dar uma dica e uma forma simples para entendimento ficarei grato.
×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.