Deixa eu dar um pitaco aqui.
Se em uma query de 10 tabelas, em modo choose, uma delas possuir
estatísticas, o otimizador usa estatísticas default para as demais tabelas e
vai, provavelmente, eleger um plano pouco apurado.

ops$marcio:LX92> create table t1 as select * from all_objects;

Table created.

ops$marcio:LX92> create table t2 as select * from all_objects;

Table created.

ops$marcio:LX92> create table t3 as select * from all_objects;

Table created.

ops$marcio:LX92> create unique index t3_idx on t3 ( object_id );

Index created.

ops$marcio:LX92> create unique index t2_idx on t2 ( object_id );

Index created.

ops$marcio:LX92> show parameter optimizer

NAME                                 TYPE        VALUE
------------------------------------ -----------
--------------------------------------------------
optimizer_mode                       string      CHOOSE

ops$marcio:LX92> begin
  2     dbms_stats.gather_table_stats( user, 'T1' );
  3  end;
  4  /

PL/SQL procedure successfully completed.

Bom, até aqui, 3 tabelas grandinhas 2 índices nas 2 últimas e coleta de
estatísticas na primeira, ou seja, em somente uma tabela.

ops$marcio:LX92> set autotrace on
ops$marcio:LX92> select t3.object_name
  2    from t1, t2, t3
  3   where t1.object_id = t2.object_id
  4     and t2.object_id = t3.object_id
  5     and t1.object_id = 100
  6  /

OBJECT_NAME
------------------------------
TRUSTED_LIST$

1 row selected.


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=46 Card=1 Bytes=48)
   1    0   NESTED LOOPS (Cost=46 Card=1 Bytes=48)
   2    1     NESTED LOOPS (Cost=2 Card=1 Bytes=43)
   3    2       TABLE ACCESS (BY INDEX ROWID) OF 'T3' (Cost=2 Card=1
Bytes=30)
   4    3         INDEX (UNIQUE SCAN) OF 'T3_IDX' (UNIQUE) (Cost=1 Card=1)
   5    2       INDEX (UNIQUE SCAN) OF 'T2_IDX' (UNIQUE)
   6    1     TABLE ACCESS (FULL) OF 'T1' (Cost=44 Card=1 Bytes=5)

Reparem no plano de execução, ele mostra (Cost, Card e Bytes para TODAS as
tabelas, ou seja, ele entrou com os valores default de estatística para as
quais ele não conhecia e baseado nisso ele decidiu o plano. Abaixo, vou
excluir as estatísticas da tabela t1 e executar a query novamente.

ops$marcio:LX92> analyze table t1 delete statistics;

Table analyzed.

ops$marcio:LX92> select t3.object_name
  2    from t1, t2, t3
  3   where t1.object_id = t2.object_id
  4     and t2.object_id = t3.object_id
  5     and t1.object_id = 100
  6  /

OBJECT_NAME
------------------------------
TRUSTED_LIST$

1 row selected.


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   NESTED LOOPS
   2    1     NESTED LOOPS
   3    2       TABLE ACCESS (FULL) OF 'T1'
   4    2       INDEX (UNIQUE SCAN) OF 'T2_IDX' (UNIQUE)
   5    1     TABLE ACCESS (BY INDEX ROWID) OF 'T3'
   6    5       INDEX (UNIQUE SCAN) OF 'T3_IDX' (UNIQUE)


Agora sim, RULE puro, nenhuma menção de estatística (Cost, Card e Bytes) foi
apresentada na query.
Espero que isso sane a dúvida. Resumindo, SIM ele escolhe CBO quando pelo
menos UMA tabela envolvida na query esteja com estatística coletada.


On 4/19/07, leandrofff <[EMAIL PROTECTED]> wrote:
>
>   isso mesmo Andre, essa é a duvida que tenho.
> Pelo que vi o Oracle não realiza coleta das tabelas envolvidas, porem
> plano de execução é alterado. Não é o mesmo que sem estatistica, RULE.
>
> --- Em oracle_br@yahoogrupos.com.br <oracle_br%40yahoogrupos.com.br>,
> "Andre Santos"
> <[EMAIL PROTECTED]> escreveu
> >
> > Leandro
> >
> > Pelo que me lembro de um curso da versão 9i, isso daria um trabalho
> extra ao
> > Oracle: ele faria a coleta de estatísticas das tabelas que
> estivessem sem,
> > cada vez que executasse a consulta.
> >
> > Mas nunca fiz testes sobre isso, nem procurei confirmação na
> documentação do
> > Oracle. Ok?
> >
> > Se você encontrar uma confirmação (ou refutação), por favor, compartilhe
> > conosco.
> >
> > [ ]
> >
> > André
> >
> >
> > Em 19/04/07, leandrofff <[EMAIL PROTECTED]> escreveu:
>
> > >
> > > de qualquer forma o otimizador será CHOOSE, porem sem
> estatistica ele
> > > executará como RULE, o que será a mesma coisa que colocar um HINT
> > > /*+RULE*/ na minha SELECT.
> > > A minha dúvida é que uma parte das tabelas tem estatistica e outra
> > > não. O que o Oracle faz?
> > > coleta estatistica para as demais tabelas envolvidas ou ignora as
> > > estatisticas e usa o otimizador com RULE?
> > >
> > > mesmo assim grato!
> > >
> > > --- Em oracle_br@yahoogrupos.com.br 
> > > <oracle_br%40yahoogrupos.com.br><oracle_br%40yahoog
> rupos.com.br>,
> > > Rodrigo Mufalani <mufalani@>
> > > escreveu
> > > >
> > > > Tire um trace da sessão onde a query é executada, com isso vai ter
> > > > mostrar a informação que vc deseja. Aqui abaixo um exemplo de trace
> > > > da instrução select count(*) from dual;
> > > >
> > > > ALTER SESSION SET SQL_TRACE = TRUE;
> > > >
> > > > SELECT COUNT(*)
> > > > FROM dual;
> > > >
> > > > ALTER SESSION SET SQL_TRACE = FALSE;
> > > >
> > > >
> > > >
> > >
> > >
>
> ********************************************************************************
> > > > count = number of times OCI procedure was executed
> > > > cpu = cpu time in seconds executing
> > > > elapsed = elapsed time in seconds executing
> > > > disk = number of physical reads of buffers from disk
> > > > query = number of buffers gotten for consistent read
> > > > current = number of buffers gotten in current mode (usually for
> update)
> > > > rows = number of rows processed by the fetch or execute call
> > > >
> > >
> > >
>
> ********************************************************************************
> > > >
> > > > SELECT COUNT(*)
> > > > FROM dual
> > > >
> > > > call count cpu elapsed disk query current rows
> > > > ------- ----- ----- ------- ------- ------- ------- -------
> > > > Parse 1 0.02 0.02 0 0 0 0
> > > > Execute 1 0.00 0.00 0 0 0 0
> > > > Fetch 2 0.00 0.00 0 1 4 1
> > > > ------- ----- ----- ------- ------- ------- ------- -------
> > > > total 4 0.02 0.02 0 1 4 1
> > > >
> > > > Misses in library cache during parse: 1
> > > > Optimizer goal: CHOOSE
> > > > Parsing user id: 121
> > > >
> > > > Rows Row Source Operation
> > > > ------- ---------------------------------------------------
> > > > 1 SORT AGGREGATE
> > > > 1 TABLE ACCESS FULL DUAL
> > > >
> > > >
> > > > No Oracle 9i, com o otimizador CHOOSE sem estatística coletada o
> banco
> > > > funciona como RULE.
> > > > Se em uma query que realiza junção de tabelas, por exemplo 5 tabelas
> > > > envolvidas, houver estatística coletada em duas tabelas e as
> demas sem
> > > > estatisticas qual otimizador o Oracle ira utilizar (CHOOSE ou RULE)?
> > > >
> > > >
> > > >
> > > >
> > > >
> > > ----------------------------------------------------------
> > > > Aqui na Oi Internet você ganha ou ganha. Além de acesso grátis com
> > > > qualidade, ganha contas ilimitadas de email com 1 giga cada uma.
> Ganha
> > > > espaço ilimitado para hospedar sua página pessoal. Ganha flog,
> suporte
> > > > grátis e muito mais. Baixe grátis o Discador em
> > > > http://www.oi.com.br/discador e comece a ganhar.
> > > >
> > > > Agora, se o seu negócio é voar na internet sem pagar uma fortuna,
> > > > assine Oi Internet banda larga e ganhe modem grátis. Clique em
> > > > http://www.oi.com.br/bandalarga e aproveite essa moleza!
> > > >
> > >
> > >
> > >
> >
> >
> > [As partes desta mensagem que não continham texto foram removidas]
> >
>
>  
>



-- 
Marcio Portes
Material Tecnico em Portugues - http://mportes.blogspot.com
Practical Learning Oracle     -
http://mportes.blogspot.com/2006/02/practical-learning-oracle.html


[As partes desta mensagem que não continham texto foram removidas]

Responder a