is null performance

DBA Geral (instalação, configuração do banco, scripts do Sql*Plus, shell scripts, batch scripts, etc...)
Responder
thiago.sousa
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 28
Registrado em: Sex, 09 Dez 2005 9:17 am
Localização: Itajai-SC
_______________________________________
Thiago Antonio
SCJP - Sun Certified Java Programer
SCJA - Sun Certified Java Associate

alguém saberia me explicar porque o uso do 'is null' em uma consulta SQL diminui bastante a performance do banco, fazendo uso excessivo do processador?
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Eu posso estar enganado, mas que eu saiba, o NULL não entra nos índices. Tipo, o oracle só coloca no índice valores NOT NULL. Por isso, quando você busca os NULL, ele tem que fazer um FULL SCAN...

Alguém sabe se minha resposta confere ?
Esse é um bom tema pra discussão aqui!...
thiago.sousa
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 28
Registrado em: Sex, 09 Dez 2005 9:17 am
Localização: Itajai-SC
_______________________________________
Thiago Antonio
SCJP - Sun Certified Java Programer
SCJA - Sun Certified Java Associate

Realmente eu tinha muito interesse em saber sobre isso...
e como será que a gente consegue resolver isso?
gilbertoca
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 372
Registrado em: Ter, 24 Jan 2006 3:33 pm
Localização: Palmas - TO
Contato:

Talvez este link http://www.dba-oracle.com/oracle_tips_null_idx.htm possa ajudar. Outra coisa, eu costumo criar minhas colunas com um valor default.

Gilberto
thiago.sousa
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 28
Registrado em: Sex, 09 Dez 2005 9:17 am
Localização: Itajai-SC
_______________________________________
Thiago Antonio
SCJP - Sun Certified Java Programer
SCJA - Sun Certified Java Associate

sim...eu tb crio as minhas colunas sempre com default.
o que eu quero dizer é o seguinte

ex:

Selecionar tudo

  select * from teste 
  where
    (campo1 = :parametro1 or :parametro1 is null)
entendeu?

como eu faço pra otimizar isto?
gilbertoca
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 372
Registrado em: Ter, 24 Jan 2006 3:33 pm
Localização: Palmas - TO
Contato:

Selecionar tudo

 select * from teste
where
(campo1 = :parametro1 or :parametro1 is null)
Este comando não está errado? Não deveria ser:

Selecionar tudo

nomedacouluna = :parametro
?
Acho que nenhum driver jdbc ira reconhecer somente este comando :parametro. você quer montar uma sql dinamica passando a coluna que você precisa usar?
entendeu?
Como você viu, não!
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

gilbertoca escreveu:Este comando não está errado?
Esse comando é bem comum sim, quando se tem parâmetros opcionais.

Exemplo:
Todos registros da EMP:

Selecionar tudo

SQL> select * from emp;

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
      7566 JONES      MANAGER         7839 02-APR-81       2975                    20
      7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30
      7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30
      7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
      7788 SCOTT      ANALYST         7566 19-APR-87       3000                    20
      7839 KING       PRESIDENT            17-NOV-81       5000                    10
      7844 TURNER     SALESMAN        7698 08-SEP-81       1500          0         30
      7876 ADAMS      CLERK           7788 23-MAY-87       1100                    20
      7900 JAMES      CLERK           7698 03-DEC-81        950                    30
      7902 FORD       ANALYST         7566 03-DEC-81       3000                    20
      7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

14 rows selected.
Agora, vamos criar uma variável BIND.

Selecionar tudo

SQL> var vjob varchar2(20)
SQL> select * from emp where job = :vjob;

no rows selected
Agora, vamos aplicar o método:
Como VJOB está nulo, tem que trazer tudo da tabela.

Selecionar tudo

SQL> select * from emp where (job = :vjob or :vjob is null);

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
      7566 JONES      MANAGER         7839 02-APR-81       2975                    20
      7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30
      7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30
      7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
      7788 SCOTT      ANALYST         7566 19-APR-87       3000                    20
      7839 KING       PRESIDENT            17-NOV-81       5000                    10
      7844 TURNER     SALESMAN        7698 08-SEP-81       1500          0         30
      7876 ADAMS      CLERK           7788 23-MAY-87       1100                    20
      7900 JAMES      CLERK           7698 03-DEC-81        950                    30
      7902 FORD       ANALYST         7566 03-DEC-81       3000                    20
      7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

14 rows selected.
Agora, vamos setar um valor pra VJOB:

Selecionar tudo

SQL> begin
  2    :vjob :='SALESMAN';
  3  end;
  4  /

PL/SQL procedure successfully completed.

SQL> select * from emp where (job = :vjob or :vjob is null);

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
      7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30
      7844 TURNER     SALESMAN        7698 08-SEP-81       1500          0         30

4 rows selected.

SQL> 
Sacou?

Acho que pra resolver o problema do nosso amigo, temos que descobrir se a coluna dele tem índice, se as estatísticas do banco foram coletadas recentemente, os outros relacionamentos da tabela, etc...

Acho que um trace ajudaria a saber qual é o join que está lento.
thiago.sousa
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 28
Registrado em: Sex, 09 Dez 2005 9:17 am
Localização: Itajai-SC
_______________________________________
Thiago Antonio
SCJP - Sun Certified Java Programer
SCJA - Sun Certified Java Associate

na verdade, o problema é sempre com os is nulll....se você fizer um teste ira verificar a diferença que acontece no banco.
Eu gostaria de saber o porque disso? e como eu resolveria
gilbertoca
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 372
Registrado em: Ter, 24 Jan 2006 3:33 pm
Localização: Palmas - TO
Contato:

Esse comando é bem comum sim, quando se tem parâmetros opcionais.
Pode usar bastante recurso do banco e causar um problemão para fazer tunning. Bom, é a opnião de um newbie :)!
Para mim neste comando,

Selecionar tudo

SQL> select * from emp where (job = :vjob or :vjob is null);
você não está usando inteiramente a opção is null! Por quê? No meu ponto de vista esta consulta irá ser traduzida para

Selecionar tudo

SQL> select * from emp where (job = null or null is null);
                                                  falso        verdadeiro
ou seja, o mesmo que

Selecionar tudo

select * from emp where (job = null or 1=1);
select * from emp where (1=1);
resultando em um full table scan. Esperimente e você verá!

Ao passo que

Selecionar tudo

SQL> select * from emp where (job = :vjob or :vjob is null);
será

Selecionar tudo

SQL> select * from emp where (job = 'SALESMAN' or SALESMAN is null);
                                                 verdadeiro               falso
quando a variabel for:

Selecionar tudo

vjob := 'SALESMAN'.
Rapaz este negócio é complicado mesmo! Ta me deixando confuso! Vou ler e praticar um pouco mais.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 13 visitantes