Ola pessoal,Neste post vou falar sobre um tuning simples, mas eficaz quando trabalhamos com valores nulos em filtros.Antes de tudo, contextualizando:O que e uma tabela?R. Uma tabela e um objeto do tipo SEGMENTO no banco de dados que armazena dados em forma de linhas e colunas, certo? Tipo uma planilha do excel:O que e um indice?R. Indice e outro objeto do tipo SEGMENTO que, uma vez criado em uma tabela por exemplo podera ser utilizado para agilizar a pesquisa quando alguns criterios forem utilizados. Imagine um indice de um livro. Ele e feito para agilizar a pesquisa e voce encontrar o assunto que esta procurando de forma mais rapida. No banco de dados e similar, o indice e constituido basicamente do valor da coluna (ou colunas) indexada da tabela com um ponteiro que aponta para a linha (ou linhas) que possui aquele valor. Basicamente assim:- Funcoes e um objeto de codigo de programacao que retorna algum valor. Por exemplo: a funcao SUM retorna o somatorio dos valores, a funcao AVG a media de valores, a funcao MIN retorna o valor minimo de uma determinada coluna, a funcao UPPER transforma valores minusculos em maiusculos. Por exemplo:SELECT UPPER('texto') FROM DUAL;-- Retorno da consulta usando a funcao:TEXTOAgora vamos pra questao em si.Imagine agora uma tabela chamada TB_ALUNOS em que ha uma coluna chamada TELEFONE. Nesta coluna TELEFONE sao cadastrados os TELEFONES dos alunos, mas voce percebe que nesta coluna sao permitidos valores NULOS, ou seja, permite que nenhum telefone seja inserido. Alem disso voce cria um indice nesta coluna TELEFONE para agilizar pesquisas filtradas pelo telefone. Ate ai tudo bem, mas diante disso voce quer saber quais alunos NAO possuem telefones cadastrados. O que voce faz? Traduzindo para a linguagem SQL seria assim:SELECT * FROM tb_alunos WHERE telefone IS NULL;ou SELECT * FROM tb_alunos WHERE telefone='';- Exemplo de criacao de um indice comum na coluna TELEFONE do exemplo:CREATE INDEX idx_alunos_telefone ON tb_alunos(telefone);O plano de execucao gerado para a consulta acima realizaria um FULL TABLE SCAN (FTS) mesmo se o indice fosse criado (levariam aproximadamente 9 minutos de execucao):Execution Plan----------------------------------------------------------Plan hash value: 2837633100-------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 57664 | 2027K| 44448 (1)| 00:08:54 ||* 1 | TABLE ACCESS FULL| TB_ALUNOS | 57664 | 2027K| 44448 (1)| 00:08:54 |-------------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - filter("TELEFONE" IS NULL)Quando usamos um filtro procurando por valores NULOS em uma tabela, o banco de dados executa um FTS (Full Table Scan) que e uma leitura COMPLETA da tabela por linhas que possuem valores NULOS, ou seja, alunos que nao possuem telefones cadastrados. Como o valor NULO na verdade e a ausencia de valor, ou seja, NADA foi gravado naquela coluna, entao como indexar?Quando voce criou um indice para aquela coluna, todos os valores que nao existiam (NULOS) tambem nao existiam no indice. Entao o Oracle nao teria como usar o indice para saber quais seriam os valores NULOS.Existe duas formas mais conhecidas de contornar (leia-se "workaround" ou "adaptacoes tecnicas").1. Criando um indice baseado