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]