Ajuda Performance-Comparacao entre mesma tabela muito lenta

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
jcemb
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 3
Registrado em: Ter, 11 Jan 2011 8:58 am
Localização: Rio de Janeiro

Pessoal, minha primeira vez aqui e já comeco com um problema dos grandes. Irei primeiro explicar o cenario e depois o problema.
O cliente possui uma tabela J2AATIVT com milhoes de registros. Essa tabela possui 2 campos como indice J2AIDATI (identificador do registro - campo unico na tabela) e J2AIDCTS (identificador do sistema) alem de varios campos VARCHAR2.
O cliente necessita que seja construida uma procedure que compare os registros dessa mesma tabela, so que a comparacao não utiliza indice, a comparacao precisa ser feita nos campos varchar2 e para piorar utilizando like, segue exemplo:

Selecionar tudo

SELECT ORIGEM.*, DESTINO.* 
FROM  (SELECT * FROM J2AATIVT A WHERE A.J2AIDCTS = 6) ORIGEM 
      , (SELECT * FROM J2AATIVT C WHERE C.J2AIDCTS = 1 ) DESTINO 
WHERE 
(ORIGEM.J2ANUMPL IS NOT NULL AND DESTINO.J2ANUMPL IS NOT NULL) AND (ORIGEM.J2ANUMPL <> ' ' AND DESTINO.J2ANUMPL <> ' ') AND (ORIGEM.J2ANUMPL like '%' || DESTINO.J2ANUMPL || '%' OR DESTINO.J2ANUMPL like '%' || ORIGEM.J2ANUMPL || '%')
OR ((ORIGEM.J2ANUMTI IS NOT NULL AND DESTINO.J2ANUMTI IS NOT NULL) AND (ORIGEM.J2ANUMTI <> ' ' AND DESTINO.J2ANUMTI <> ' ') AND (ORIGEM.J2ANUMTI like '%' || DESTINO.J2ANUMTI || '%' OR DESTINO.J2ANUMTI like '%' || ORIGEM.J2ANUMTI || '%')); 
Como voces podem ver, e criado 2 sub-queries, onde a Origem lista todos os registros pertencentes ao sistema (J2AIDCTS) 6 e o Destino, sistema 1. Alem disso a comparacao entre as sub-queries e feita utilizando (ORIGEM LIKE DESTINO) OR (DESTINO LIKE ORIGEM). E para piorar mais um pouco a comparacao não e feita apenas nessas 2 colunas e sim em 10 colunas, no mesmo formato e para piorar ainda mais a comparacao no exemplo esta acontecendo apenas entre origem e destino, sistemas 6 e 1, mas o cliente quer que a comparacao seja feita entre a origem e todos os sistemas que existem na base (hoje existem 10), portanto, seriam 9 destinos.
já coloquei isso na query e vi que ficou inviavel, a não ser que exista outro tipo de comparacao mais eficaz que eu desconheca.
Estava pensando em fazer essas comparacoes separadas, guardar na memoria em cursores e depois fazer a comparacao entre todos os sistemas num loop, mas ainda assim acho que ficara muito lento e pesado.
não sei se ficou muito complicado o entendimento, mas caso não entendam algo e so perguntar.
Estou aberto a sugestoes e realmente estou precisando muito de alguma ajuda...
Abs....
burga
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Qui, 26 Nov 2009 1:05 pm
Localização: SP
Ricardo H. Tajiri

A única idéia que me vem a cabeça é utilizar MATERIALIZED VIEW, pois com esses LIKE fica um pouco difícil mesmo obter uma performance legal... Vão ser 2 ou até mais (10) FTS na tabela de milhões de registros. E do jeito que está não tem muito o que fazer... Não dá pra fazer milagres.
jcemb
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 3
Registrado em: Ter, 11 Jan 2011 8:58 am
Localização: Rio de Janeiro

então cara, eu já tinha pensado nisso, não há muito o que fazer na query para melhorar, mas você ou alguém sugere alguma proc? Alguma acao para desmembrar essa query e a performance do processo?
burga
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Qui, 26 Nov 2009 1:05 pm
Localização: SP
Ricardo H. Tajiri

Talvez a criação de um índice context e ao invés de usar o LIKE '%NOME%', usar o CONTAINS...

Talvez isto possa melhorar a performance da consulta, mas pode piorar outros aspectos da aplicação. Ou ainda fazer isto em tabelas "temporárias" com índices context, pra não atrapalhar nas tabelas de dados correntes...

Mas não sei uma forma de melhorar muito isso sem mexer no banco.
hugo_roberto
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Sex, 12 Nov 2010 10:07 am
Localização: SP
Hugo Roberto Souza Santos

velho, não tem relacionamento entre as subqueries, provavelmente está realizando um grande artesiano.
jcemb
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 3
Registrado em: Ter, 11 Jan 2011 8:58 am
Localização: Rio de Janeiro

Galera, valeu pelas respostas, aconteceu o que eu já imaginava, essa query e inviavel. Estou tentando criar cursores que facam esse trabalho mais rapido...
Obrigado.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Olá,

Em cursor vai expor ainda mais os problemas, pois na prática vai se tornar um faça-você-mesmo nested loop join.

O ideal seria analisar a fundo os requisitos dessa consulta, verificar como são os dados da tabela, as cardinalidades de dados de cada coluna.

Por exemplo, tem algumas condições redundantes no Where:
Se ORIGEM.J2ANUMPL é diferente de ' ', por consequência ele é NOT NULL. Logo a condição de not null é desnecessária e talvez esteja prejudicando o desempenho na avaliação da consulta.

Pelo que entendi essa consulta tenta fazer um Join meio condicional: ou faz o join por uma condição ou faz por outra. Você poderia partir a query em várias, cada um fazendo um predicado do OR e executando-as em separado.

A condição do join "de verdade", me parece que é verificar se o campo origem está contido no conteúdo do campo destino, e vice versa. Uma forma de tentar acelerar bastante a avalidação dessa condição do LIKE talvez seja usando function-based index. Se você puder nos mostar melhor como é o conteúdo dessas colunas do like (J2ANUMPL, J2ANUMTI), talvez dê para derivar uma expressão regular que indentifique o padrão da pesquisa e colocá-la num function-based index.
Responder
  • Informação
  • Quem está online

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