Pois é : eu mesmo há alguns anos, na primeira vez que fui mexer com DW (que
logo de cara já era uma base de uns 7 Tb) deixei o pessoal boquiaberto fazendo
rotinas de muitas horas processarem em 40 minutos, e o segredo foi esse,
executar num só UPDATE, ou num só INSERT, o processamento que estava em cursor
aninhado dentro de cursor, naquela lógiquinha tipo :
for r in select que lê tabela de trabalho loop
for x in select que traz os dados complementares para cada registro
principal ...
select lookup...
insert into tabeladestino..
transformei isso num :
INSERT /*+ APPEND */ into tabeladestino
(select com join entre as tabelas todas);
com paralelismo, SEM índices (que depois foram recriados com parallel e nolog)
e o negócio decolou, BASICAMENTE por causa de não ter que atualizar o índice a
cada conjunto de linhas, por não ter context switch, etc, etc, etc... É aquele
negócio, cada caso é um caso, mas que optar PRIMEIRO por um approach SQL-only
na maior parte das vezes compensa, isso não tem dúvida...
[]s
Chiappa
--- Em [email protected], Júlio César Corrêa <juliotubi...@...>
escreveu
>
> Chiappa.Gostei desta regra de ouro.Hoje mesmo estava explicando para uma
> desenvolvedor estes conceitos,tem uma procedure de carga do SAP que demora
> horas e horas,como cheguei na empresa na segunda-feira ainda estou
> levantando informações,fazendo o reconhecimento de campo nos servidores de
> banco dados e etc.
> Mas fiz uma análise nas 2 procedures e encontrei relamente pontos a melhorar
> de cara.
>
> -Uso desnecessário de ORDER BY.
> - Uso de cursor/loop em todos as queries
> - Poderia usar bulk,uso de limit no bulk.já que o processo é selecionar e
> inserir somente.ou inser select
> -- o commit periódico é uma aberração,a pessoa nem testou,não
> acreditei.Rodar roda,mas nunca termina rs.
> - Várias,mais várias variáveis declaradas e não usadas.Tem até algumas que
> são atribuidas valor e nunca se faz nada com isso."Código porquinho
> mesmo,copiado sem noção e colado".
>
> Gostei do termo "regra de ouro" ,posso usá-la com nas situações
> necessárias?rs
>
> é sempre bom mostrar estes conceitos ,desta forma que vocÊ passou.
>
> ótimo.
>
> Abs,
>
> Vlw,
>
> JC
>
> 2009/5/27 jlchiappa <jlchia...@...>
>
> >
> >
> > Não vai rolar, não, afaik André : Marcos, a questão número 1 é de conceito,
> > que o índice de função só tem a função executada (e portanto é atualizado)
> > só na hora do DML, então ** não ** faz muito sentido se querer usar
> > data/hora ou alguma informação que muda "sozinha", sem DML na tabela-origem,
> > como é o caso do TEMPO, que avança e muda sem que hajam DMLs, OU informação
> > que está em outra tabela, ok ? Pelo que eu entendo, vc vai usar a função num
> > SQL tipo :
> >
> > SELECT ... FROM outratabelaquenãoausadanafunção X
> > WHERE FUNCAO_USUARIO (X.ID, X.DT_REFERENCIA) = valorqueindicapresença
> >
> > certo ? Num caso desses, DMLs na tabela tabela_exemplo usada na função VÃO
> > ocorrer e (óbvio) não vão atualizar a tabela outratabelaquenãoausadanafunção
> > , simplesmente Não ROLA, não faz sentido...
> >
> > A segunda coisa é : ** please **, please, se vc quer máxima performance
> > pelo amor de qquer coisa Não Use funções PL/SQL no meio dos seus SQLs como o
> > exposto acima, isso ** TEM ** um custo em performance que normalmente não é
> > zero, pelo seguinte :
> >
> > a) vc está causando um CONTEXT SWITCH, o banco ** tem ** que "pular" do SQL
> > engine para o PL/SQL engine, isso não é de graça
> >
> > b) cardinalidade : o coitado do CBO **** NÂO TEM COMO **** "adivinhar" que
> > a sua função vai retornar só uma linha, então a estimativa dele de custo vai
> > ser TOTALMENTE na base do chute - já se vc tiver uma constraint de PK, e/ou
> > um índice unique em (ID, DT_REFERENCIA) com uma construção do tipo :
> >
> > SELECT ... FROM outratabelaquenãoausadanafunção X,
> > tabelaexemplo Y
> > WHERE Y.id_fk = X.ID
> > AND Y.dt_data = X.DT_REFERENCIA
> > AND Y.id_fk = :pID
> > AND Y.dt_data = :pDT_REFERENCIA
> > AND X.ID = :pID
> > AND X.DT_REFERENCIA = :pDT_REFERENCIA;
> >
> > aí SIM o CBO tem a informação necessária para concluir que vc está passando
> > a chave completa E portanto a junção retorna só uma linha.... Esconder
> > informação do CBO é muitas vezes QUEBRAR as pernas do coitado...
> >
> > Isso que eu falei ** não é ** novidade, pesquise em
> > http://asktom.oracle.com por CONTEXT SWITCH e por USER FUNCTION
> > CARDINALITY que vc vai achar n+1! referencias sobre isso... A regra de ouro
> > pra performance é CLARA :
> >
> > a) fazer pesquisas e manipulação de dados NUM ÚNICO SQL
> > b) se REALMENTE não der pra seguir a), ter POUCOS SQLs executados numa
> > transação, mas sem cursor/loop
> > c) se REALMENTE não der pra seguir b), usar BULK COLLECT e array processing
> > em PL/SQL
> > d) se REALMENTE não der pra seguir b), usar C ou java
> >
> > []s
> >
> > Chiappa
> >
> > --- Em [email protected] <oracle_br%40yahoogrupos.com.br>,
> > Andre Santos <andre.psantos.ti@> escreveu
> >
> > >
> > > Marcos
> > >
> > > Neste caso, a sua função na realidade é uma "query"...
> > > Talvez você possa fazer um "join" ao invés de usar essa função.
> > >
> > > Já criei índices baseados em função, mas foram sempre para funções com um
> > > algoritmo (cálculo, por exemplo).
> > > Nunca tentei fazer um FBI com uma função que retornasse o resultado de
> > uma
> > > consulta... não sei se a opção DETERMINISTIC funcionaria nesse caso. Você
> > já
> > > testou? Se testou, qual foi a mensagem de erro?
> > >
> > > [ ]
> > >
> > > André
> > >
> > > 2009/5/25 Marcos Grimm <marcosgrimm@>
> >
> > >
> > > >
> > > >
> > > > Boa tarde pessoal,
> > > >
> > > > Meu nome é Marcos Grimme sou participante do grupo faz algum tempo já,
> > mas
> > > > sempre fico apenas observando as treads que acontecem.
> > > >
> > > > Eis que chegou o dia que eu mando aqui um problema que estou
> > enfrentando:
> > > >
> > > > Estou escrevendo uma query SQL que possui várias funções PL/SQL criadas
> > por
> > > > mim, por exemplo
> > > >
> > > > FUNCTION FUNCAO_USUARIO (
> > > > pID VARCHAR2(5),
> > > > pDT_REFERENCIA DATE
> > > > )
> > > > RETURN VARCHAR2 (5)
> > > >
> > > > IS
> > > > vRETORNO VARCHAR2(5);
> > > > BEGIN
> > > > SELECT id_coluna INTO vRETORNO FROM tabela_exemplo WHERE id_fk = pID
> > AND
> > > > dt_data = pDT_REFERENCIA;
> > > > RETURN vRETORNO;
> > > > END;
> > > >
> > > > Existe alguma maneira de eu criar um índice que funcione corretamente
> > com
> > > > essa função? Esse segundo parâmetro de data, como trabalho com ele
> > dentro
> > > > de
> > > > um índice? A opção DETERMINISTIC não serve, pois os resultados podem
> > mudar
> > > > dependendo do parametro de data passado.
> > > >
> > > > Se alguem puder ajudar vou ser muito grato.
> > > >
> > > > Atenciosamente,
> > > > Marcos Grimm
> > > >
> > > > [As partes desta mensagem que não continham texto foram removidas]
> > > >
> > > >
> > > >
> > >
> > >
> > > [As partes desta mensagem que não continham texto foram removidas]
> > >
> >
> >
> >
>
>
>
> --
> Júlio César Corrêa
> IS Technologist - Oracle DBA
> www.dbajccorrea.com
>
> "To stay competitive in the tech industry, never stop
> learning. Always be on the lookout for better ways of
> doing things and new technologies. Our industry does
> not reward people who let themselves stagnate"
> John Hall, Senior Vice President, Oracle University
>
>
> [As partes desta mensagem que não continham texto foram removidas]
>