Não fazer full table scan

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
fernandomartini1984
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 8
Registrado em: Sex, 04 Out 2013 9:41 am

Bom Dia Mestres,

Estou com o seguinte problema:
Tenho uma tabela com 50 milhões de registros e preciso verificar se um campo de data está no formato correto... somente o mês especificamente.
Realizo a seguinte consulta:

Selecionar tudo

SELECT 
ROWNUM,
 TO_CHAR(CPM.dt_brasindice_versao,'MM')
FROM    CONTA_PACIENTE_MATERIAL_V CPM
WHERE 1=1
AND TO_CHAR(CPM.dt_brasindice_versao,'MM') NOT IN ('01','02','03','04','05','06','07','08','09','10','11','12')
AND ROWNUM = 1
ORDER BY 1
Utilizei o rownum com a intenção de me retornar somente o primeiro registro encontrado, afim de verificar se esse erro realmente existe nesta tabela, mas como sou um tanto leigo ainda, me informaram que mesmo assim essa consulta vai varrer toda a tabela e só então me retornar a primeira linha.

Pergunto: Qual a forma de fazer esta consulta retornar somente o primeiro resultado encontrado sem buscar em toda a tabela (Full Table Scan?) ?

Abraço!
thrrent
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Dom, 29 Jan 2012 5:28 pm
Localização: Rio de Janeiro

Acredito que se você utilizar not exists ao invés de not in a sua consulta vai deixar de fazer o full scan.
Se eu entendi bem o tipo dessa coluna é date, então não deveria conter valores menores que 01 maiores que 12 no mês, até porque qualquer tipo de insert fora dessa margem daria errado.

Uma outra forma de verificar os valores existentes, já que teoricamente são 12 meses, tente usar a ideia abaixo:

Selecionar tudo

SELECT Distinct
TO_CHAR(CPM.dt_brasindice_versao,'MM')
FROM    CONTA_PACIENTE_MATERIAL_V CPM
Outra coisa, rownum = 1 geralmente dá erro, eu sempre uso rownum <= 1.
Avatar do usuário
fbifabio
Moderador
Moderador
Mensagens: 199
Registrado em: Ter, 22 Fev 2011 1:51 pm
Localização: São Paulo - SP
Contato:
Fábio Prado
www.fabioprado.net

@fernandomartini1984,

Primeiro vamos entender alguns conceitos. NOT IN sempre invialibiliza o uso de índices btree, portanto, se você quer fazer um index scan, caso exista um índice btree correspondente na coluna dt_brasindice_versao, você não pode usar essa cláusula, ok? A unica forma de não fazer um FTS usando NOT IN é criar um índice do tipo bitmap, mas é importante ressaltar que este índice só é útil se a cardinalidade da coluna for baixa e existem ainda outros cuidados que explico no artigo http://www.fabioprado.net/2011/07/otimi ... itmap.html.

Em segundo lugar, qual é o tipo de dado da coluna "dt_brasindice_versao"? Se for date, é totalmente desnecessária a verificação NOT IN, para encontrar meses inválidos.

Em terceiro lugar, se existe índice na coluna "dt_brasindice_versao" , ele é baseado na função TO_CHAR? Se não for, um simples índice normal não seria utilizado, ok?

Tudo isso explico nos treinamentos de SQL Tuning (http://www.fabioprado.net/p/sql-tuning- ... racle.html) que eu leciono.

[]s
Paulo.Chaves
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 1
Registrado em: Ter, 26 Nov 2013 11:13 am

Opa, seguinte, se é um campo date, não faz sentido ter um mês fora do intervalo entre 1 e 12, a não ser que o banco esteja definido para o calendário Judaico, que pode ter 13 meses por ser lunar. Mas isso é outra história. Tente ver a configuração da data no banco mas, pelo que entendi, essa busca pode ser em vão.
Responder
  • Informação