Não entendi direito o que vc queria testar, mas pelo que vi vc tem uma proc com um monte de DMLs(INSERT no caso) e vc a rodou SEM e COM o índice criado, é isso ?? Se é isso, vc comprovou um conceito básico de BDs, em especial Oracle, que é : índices server pra ACELERAR SELECTs, SE puderem ser usados corretamente, ** E ** para degradar DMLs, sejam INSERTs, DELETEs ou UPDATEs, ambas as coisas estão sempre juntas. A causa é simples, quando vc faz um DML, além de mexer nos blocos da tabela, o banco TEM QUE atualizar o índice com a nova informação, e um índice é uma estrutura complexa, que obrigatoriamente TEM SEMPRE que estar ordenada, isso tem custo, então fazer DML numa tabela SEM índice é SEMPRE, por definição, mais rápido do que o mesmo DML numa tabela com índices, pois o índice tem que ser atualizado também.... Quanto aos PIOs (Physical IOs) e aos LIOs (Logical IOs), sim, vc não entendeu bem o conceito, deixa eu ver se consigo explicar : no bd Oracle, se o bloco onde há registro(s) a ser lido não está no cache, o banco vai ler no disco (isso é um PIO), ** E ** imediatamente , antes mesmo de ser usado, esse bloco TEM QUE ir pro cache, isso é um LIO. Então, TODO PIO (com exceção de blocos em tabelas GTTs, sorts/hashes, etc) no princípio gera um LIO, os PIOs ** já estão ** inclusos nos LIOs na primeira leitura do banco, é isso. Então cuidando dos LIOs vc não está desprezando os PIOs, na verdade os está cuidando de forma indireta, ok ?? O documento http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:6643159615303 no asktom ilustra o princípio, a idéia é vc PRIMEIRO focar em como alterar o SQL e/ou a estrutura do banco diminuir os LIOs, que "de embrulho" vc diminuindo os LIOs vc já baixa EM MUITO os PIOs, certo ? Feito isso, aí sim vc pode pensar nos PIOs, embora vai de regra eles já terão diminuído pracas, não deve ser possível fazer muito mais com eles. Pra ficar claro : PIOs num trace são os blocos marcados como Physical Reads, e LIOs são a soma dos blocos current gets + consistent gets. Quanto ao current/consistent get : é verdade que a leitura do cache é mais rápida do que leitura física, MAS mesmo leituras do cache ** não são ** grátis : leitura do cache implica que , na fração de segundo que eu estou lendo, ninguém pode alterar esse bloco, isso é, há um bloqueio em RAM nesse bloco, o latch. Então se vc pode obter a mesma informação lendo (digamos) 100 blocos, MAS por erro do SQL, da estrutura, o que for, vc está lendo 1000, esse SQL é ineficiente, AINDA QUE todas essas 1000 leituras tenham sido de RAM, eu fiz MUITO mais bloqueios em RAM (latches) do que o mínimo possível,estou gastando MUITO mais CPu que o mínimo necessário, a hora que esse aplicativo começar a crescer, a atender mais usuários, esses latches extras vão começar a pesar na performance, é isso.
==>> EM RESUMO : absolutamente NÂO basta vc só olhar se as leituras são físicas ou em RAm, vc tem é que tratar de fazer o MENOS de leitura de blocos possível, ok ? É isso. Esses pontos estão mais detalhadamente expostos em www.hotsos.com , no link Library escolha o paper "Why You Should Focus on LIOs Instead of PIOs", vc tem que se registrar no site mas é grátis. Quanto ao Custo no explain plan, vc obtém isso SE estiver rodando em CBO, e tiver estatísticas, é isso. []s Chiappa E o método proposto se baseia no fato de que, SE vc diminuir o número de leituras em RAM, já que muitas Consistent gets são os blocos que --- Em oracle_br@yahoogrupos.com.br, Marcelo Cauduro <[EMAIL PROTECTED]> escreveu > > Entedi, obrigado, nao sabia que o profiler era soh para pl... > > quanto ao autotrace consegui as informacoes > > COM INDICE : > > Statistics > ---------------------------------------------------------- > 0 recursive calls > 0 db block gets > 142 consistent gets > 0 physical reads > 0 redo size > 18795 bytes sent via SQL*Net to client > 8050 bytes received via SQL*Net from client > 70 SQL*Net roundtrips to/from client > 1 sorts (memory) > 0 sorts (disk) > 1000 rows processed > > SEM INDICE : > > > Statistics > --------------------------------------------------------- > 0 recursive calls > 5 db block gets > 252 consistent gets > 182 physical reads > 0 redo size > 18796 bytes sent via SQL*Net to client > 8002 bytes received via SQL*Net from client > 70 SQL*Net roundtrips to/from client > 2 sorts (memory) > 0 sorts (disk) > 1000 rows processed > > Lendo um artigo do site ASKTOM ele disse que ignora os "physical reads" , > posso mesmo fazer isso ? > Outra coisa, pelo que entendi ele leva apenas em conta o "consistent > gets".... > tem mais alguma informacao relevante de todas essas do trace ? > ou realmente a "consistent gets" é a principal > > Tendo "consistent gets" menores , a query é melhor ? é isso mesmo ? > > eu estava olhando o concepts e pelo que entendi : > physical reads -> Leitura fisica, numero de vezes que os blocos fisicos de > dados sao acessados > consistent gets -> eu li mas nào entendi.... parece que é a leitura de > memoria.... ou consitencia de memoria com disco... talvez locks... > talvez acesso ao database buffer cache.... > > mas como isso pode ser mais custoso do que leitura fisica ? > > e mais uma coisa.... > usar o explain plan gera o custo para fazer o select ? > pois eu executando explain for..... > e nao traz nada de custo... apenas informacoes como uso de indice etc..... > select * from plan_Table > > Muito Obrigado. > > On 1/11/06, jlchiappa <[EMAIL PROTECTED]> wrote: > > > > profiler te mostra tempo de execução do PL/SQL, pra vc ver detalhes > > sobre o SQL (ie, plano, estatísticas se usando CBO, etc), o negócio é > > trace + tkprof, ou ao menos AUTOTRACE, como mostrado lá nos exemplos > > sobre FBI que passaram há uns dias pelo grupo. > > > > []s > > > > Chiappa > > --- Em oracle_br@yahoogrupos.com.br, Marcelo Cauduro <[EMAIL PROTECTED]> > > escreveu > > > > > > Pessoal, estou fazendo o seguinte teste, para ter certeza no uso de > > um > > > indice > > > Tenho uma tabela com 40000 registro, que vai crescer muito > > ainda.,.... > > > muito muito mesmo.... > > > ela ta pequenininha... > > > > > > tem um campo date preenchido na maior parte do registros , que > > algumas vezes > > > será nullo, > > > fiz uma funcao para pegar esse nulos sem ter que usar o is nulll, e > > quero > > > ter certeza > > > de que isso signifara ganho... > > > > > > Mas não sei se o meio qual estou fazendo o uso do DBMS_Profiler é o > > > melhor... > > > essa é a melhor maneira de fazer o meu teste ? > > > > > > O teste esta abaixo e as conclusoes que cheguei são péssimas.... > > > > > > Inserções : > > > > > > Obtive : > > > ------------------------------------------------- > > > Sem indice > > > TESTE_FCT PROCEDURE 3672,726 > > > ANONYMOUS BLOCK 0,531 > > > Com indice > > > TESTE_FCT PROCEDURE 5786,678 > > > T_TRUNC FUNCTION 199,851 > > > ANONYMOUS BLOCK 0,361 > > > ao todo 5986,529 > > > > > > Com indice ficou 63% mais lento > > > ------------------------------------------------- > > > Consultas: > > > > > > Sem indice > > > 1 <anonymous> <anonymous> ANONYMOUS BLOCK 0,228 > > > Com idice > > > 1 <anonymous> <anonymous> ANONYMOUS BLOCK 0,223 > > > > > > Nao tive ganhos significativos > > > > > > > > > > > > NAO TEM ALGUM COISA ERRADA ? > > > > > > ------------------------------------------------- > > > > > > TESTE : > > > > > > 1 Passo - > > > Criar Tabela > > > > > > create table teste_function (a date,b number); > > > > > > 2 Passo - > > > Criar function de indice: > > > > > > create or replace function t_trunc(a date) return NUMBER > > deterministic > > > as > > > begin > > > -- > > > if a is NOT null then > > > -- > > > return null; > > > -- > > > end if; > > > -- > > > return 1; > > > -- > > > end; > > > > > > 3 Passo : > > > > > > Usar o dbms_profiler para verificar quanto demora para inserir > > sem a > > > funcao com indice e ver a perda, > > > e ver se compensa na hora de fazer as queries > > > > > > -- Dispara o profiler > > > select decode(dbms_profiler.start_profiler, '0', 'Profiler > > started', > > > 'Profiler error') > > > from dual; > > > > > > create or replace procedure teste_fct as > > > begin > > > for ct in 1..20000 loop > > > insert into teste_function values (sysdate,1); > > > end loop; > > > end; > > > > > > call teste_fct() > > > > > > -- Execute o código > > > > > > -- Para a execução > > > select decode(dbms_profiler.stop_profiler, '0', 'Profiler > > stopped', > > > 'Profiler error') > > > from dual; > > > -- Salva nas tabelas > > > select decode(dbms_profiler.flush_data, '0', 'Profiler > > flushed', 'Profiler > > > error') > > > from dual; > > > -- Retorna o número do processo > > > select 'runid:' || plsql_profiler_runnumber.currval > > > from dual; > > > > > > select u.unit_owner, u.unit_name, u.unit_type, sum > > (d.total_time/1000000) > > > as total_time > > > from plsql_profiler_data d, plsql_profiler_units u > > > where u.runid = d.runid > > > and u.runid = 137 --> insira o número do processo > > > and u.unit_number = d.unit_number > > > group by u.unit_owner, u.unit_name, u.unit_type > > > order by total_time desc > > > > > > Obtive : > > > TESTE_FCT PROCEDURE 3672,726 > > > ANONYMOUS BLOCK 0,531 > > > > > > 4 Passo : > > > > > > Usar o dbms_profiler para verificar quanto demora para inserir > > com a > > > funcao com indice e ver a perda, > > > e ver se compensa na hora de fazer as queries > > > > > > --> Criei dois indices para teste, um usando uma funcao do > > sistema (a > > > trunc) e outro usando uma funcao criado por mim > > > > > > create index ITESTANDO_FUNCTION on teste_function(t_trunc(a)) > > > > > > -- Dispara o profiler > > > select decode(dbms_profiler.start_profiler, '0', 'Profiler > > started', > > > 'Profiler error') > > > from dual; > > > > > > create or replace procedure teste_fct as > > > begin > > > for ct in 1..20000 loop > > > insert into teste_function values (sysdate,1); > > > end loop; > > > end; > > > > > > call teste_fct() > > > > > > -- Execute o código > > > > > > -- Para a execução > > > select decode(dbms_profiler.stop_profiler, '0', 'Profiler > > stopped', > > > 'Profiler error') > > > from dual; > > > -- Salva nas tabelas > > > select decode(dbms_profiler.flush_data, '0', 'Profiler > > flushed', 'Profiler > > > error') > > > from dual; > > > -- Retorna o número do processo > > > select 'runid:' || plsql_profiler_runnumber.currval > > > from dual; > > > > > > select u.unit_owner, u.unit_name, u.unit_type, sum > > (d.total_time/1000000) > > > as total_time > > > from plsql_profiler_data d, plsql_profiler_units u > > > where u.runid = d.runid > > > and u.runid = 138 --> insira o número do processo > > > and u.unit_number = d.unit_number > > > group by u.unit_owner, u.unit_name, u.unit_type > > > order by total_time desc > > > > > > TESTE_FCT PROCEDURE 5786,678 > > > T_TRUNC FUNCTION 199,851 > > > ANONYMOUS BLOCK 0,361 > > > > > > 6 Passo : > > > > > > --> insere valores null > > > create or replace procedure teste_fct as > > > begin > > > for ct in 1..1000 loop > > > insert into teste_function values (null,1); > > > end loop; > > > end; > > > > > > call teste_fct() > > > > > > > > > 7 Passo : > > > > > > Busca sem indice > > > > > > -- Dispara o profiler > > > select decode(dbms_profiler.start_profiler, '0', 'Profiler > > started', > > > 'Profiler error') > > > from dual; > > > > > > -- Execute o código > > > select * from teste_function > > > where a is null; > > > > > > -- Para a execução > > > select decode(dbms_profiler.stop_profiler, '0', 'Profiler > > stopped', > > > 'Profiler error') > > > from dual; > > > -- Salva nas tabelas > > > select decode(dbms_profiler.flush_data, '0', 'Profiler > > flushed', 'Profiler > > > error') > > > from dual; > > > -- Retorna o número do processo > > > select 'runid:' || plsql_profiler_runnumber.currval > > > from dual; > > > > > > select u.unit_owner, u.unit_name, u.unit_type, sum > > (d.total_time/1000000) > > > as total_time > > > from plsql_profiler_data d, plsql_profiler_units u > > > where u.runid = d.runid > > > and u.runid = 145 --> insira o número do processo > > > and u.unit_number = d.unit_number > > > group by u.unit_owner, u.unit_name, u.unit_type > > > order by total_time desc > > > > > > 1 <anonymous> <anonymous> ANONYMOUS BLOCK 0,241 > > > > > > 8 Passo : > > > > > > Busca com indice > > > > > > -- Dispara o profiler > > > select decode(dbms_profiler.start_profiler, '0', 'Profiler > > started', > > > 'Profiler error') > > > from dual; > > > > > > -- Execute o código > > > select /*+ INDEX(teste_function ITESTANDO_FUNCTION) */ * from > > > teste_function > > > where t_trunc(a)=1; > > > > > > -- Para a execução > > > select decode(dbms_profiler.stop_profiler, '0', 'Profiler > > stopped', > > > 'Profiler error') > > > from dual; > > > -- Salva nas tabelas > > > select decode(dbms_profiler.flush_data, '0', 'Profiler > > flushed', 'Profiler > > > error') > > > from dual; > > > -- Retorna o número do processo > > > select 'runid:' || plsql_profiler_runnumber.currval > > > from dual; > > > > > > select u.unit_owner, u.unit_name, u.unit_type, sum > > (d.total_time/1000000) > > > as total_time > > > from plsql_profiler_data d, plsql_profiler_units u > > > where u.runid = d.runid > > > and u.runid = 143 --> insira o número do processo > > > and u.unit_number = d.unit_number > > > group by u.unit_owner, u.unit_name, u.unit_type > > > order by total_time desc > > > > > > 1 <anonymous> <anonymous> ANONYMOUS BLOCK 0,228 > > > > > > > > > [As partes desta mensagem que não continham texto foram removidas] > > > > > > > > > > > > > > > > > -------------------------------------------------------------------------------------------------------------------------- > > Atenção! As mensagens deste grupo são de acesso público e de inteira > > responsabilidade de seus remetentes. > > Acesse: http://www.mail-archive.com/oracle_br@yahoogrupos.com.br/ > > > > --------------------------------------------------------------------------------------------------------------------------_____________________________________________________________________ > > Area de download do grupo - http://www.4shared.com/dir/101727/a4dcc423 > > > > > > *Yahoo! Grupos, um serviço oferecido por:* PUBLICIDADE > > <http://br.rd.yahoo.com/SIG=12fktc4i1/M=387526.7663462.8676324.1588051/D=brclubs/S=2137114689:HM/Y=BR/EXP=1136997952/A=3221952/R=2/id=noscript/SIG=16ehti2go/*http://landingstrip.dell.com/landingstrip/ls.asp?CID=10076&LID=289961&DGC=BA&DGStor=DHS&DGSite=Yahoo&Conum=BR&DURL=http://www1.la.dell.com/content/products/category.aspx/desktops?c%3Dbr%26l%3Dpt%26s%3Ddhs> > > ------------------------------ > > *Links do Yahoo! Grupos* > > > > - Para visitar o site do seu grupo na web, acesse: > > http://br.groups.yahoo.com/group/oracle_br/ > > > > - Para sair deste grupo, envie um e-mail para: > > [EMAIL PROTECTED]<[EMAIL PROTECTED]> > > > > - O uso que você faz do Yahoo! Grupos está sujeito aos Termos do > > Serviço do Yahoo! <http://br.yahoo.com/info/utos.html>. > > > > > > > [As partes desta mensagem que não continham texto foram removidas] > -------------------------------------------------------------------------------------------------------------------------- Atenção! As mensagens deste grupo são de acesso público e de inteira responsabilidade de seus remetentes. Acesse: http://www.mail-archive.com/oracle_br@yahoogrupos.com.br/ --------------------------------------------------------------------------------------------------------------------------_____________________________________________________________________ Area de download do grupo - http://www.4shared.com/dir/101727/a4dcc423 Links do Yahoo! Grupos <*> Para visitar o site do seu grupo na web, acesse: http://br.groups.yahoo.com/group/oracle_br/ <*> Para sair deste grupo, envie um e-mail para: [EMAIL PROTECTED] <*> O uso que você faz do Yahoo! Grupos está sujeito aos: http://br.yahoo.com/info/utos.html