{"id":991,"date":"2017-03-06T22:39:56","date_gmt":"2017-03-07T01:39:56","guid":{"rendered":"http:\/\/dbtimewizard.com.br\/blog\/?p=991"},"modified":"2019-10-10T23:05:23","modified_gmt":"2019-10-11T02:05:23","slug":"histogramas-qual-importancia-deles","status":"publish","type":"post","link":"http:\/\/dbtimewizard.com.br\/blog\/histogramas-qual-importancia-deles\/","title":{"rendered":"Histogramas: Qual import\u00e2ncia deles?"},"content":{"rendered":"<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">No artigo &#8220;<strong><a href=\"http:\/\/dbtimewizard.com.br\/blog\/por-que-o-otimizador-criou-um-plano-de-execucao-ineficiente\/\" target=\"_blank\">Por que o Otimizador criou um plano de execu\u00e7\u00e3o ineficiente?<\/a><\/strong>&#8221; elencamos algumas condi\u00e7\u00f5es que levam o Otimizador a gerar um plano de execu\u00e7\u00e3o ineficiente, neste artigo vamos abordar com mais detalhes um desses t\u00f3picos, como a repeti\u00e7\u00e3o de dados n\u00e3o uniformes em uma coluna da tabela podem influenciar de maneira negativa o Otimizador.<\/span><\/p>\n<p>&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<\/p>\n<h2 style=\"text-align: justify;\"><span style=\"font-size: 14pt;\">Repeti\u00e7\u00e3o de dados n\u00e3o uniformes<\/span><\/h2>\n<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Quando o Otimizador gera\u00a0o plano de execu\u00e7\u00e3o de uma instru\u00e7\u00e3o SQL e na cl\u00e1usula WHERE dessa instru\u00e7\u00e3o existe um filtro numa coluna da tabela que possui um n\u00famero de valores distintos muito inferior ao numero total de registros da tabela, o Otimizador utiliza uma regra simples para calcular a cardinalidade, ele divide o numero total de registros da tabela pelo numero de valores distintos. Essa formula pode ser eficaz se para cada valor distinto houver uma quantidade de registros semelhante, porem ela se torna ineficaz quando um ou mais valores tem uma quantidade de registros muito superior ao outros.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Para que o Otimizador consiga calcular a cardinalidade de forma mais precisa na condi\u00e7\u00e3o apresentada acima \u00e9 necess\u00e1rio a utiliza\u00e7\u00e3o de um histograma na coluna cuja repeti\u00e7\u00e3o de dados n\u00e3o \u00e9 uniforme. Para gera\u00e7\u00e3o desse histograma devemos utilizar o pacote DBMS_STATS.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Para ver na pr\u00e1tica essa situa\u00e7\u00e3o vamos realizar as seguintes opera\u00e7\u00f5es:<\/span><\/p>\n<p style=\"text-align: left;\"><span style=\"font-size: 12pt;\">1) Criar uma tabela e coletar as estat\u00edsticas sem a gera\u00e7\u00e3o do histograma<\/span><br \/>\n<span style=\"font-size: 12pt;\">2) Executar uma consulta que utilizar\u00e1 essa tabela como fonte de dados e verificar a cardinalidade estimada pelo Otimizador <\/span><br \/>\n<span style=\"font-size: 12pt;\">3) Coletar as estast\u00edsticas da tabela gerando o histograma <\/span><br \/>\n<span style=\"font-size: 12pt;\">4) Executar a mesma consulta novamente e verificar a cardinalidade estimada pelo Otimizador<\/span><\/p>\n<h3 style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Criar a tabela<\/span><\/h3>\n<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Primeiro vamos clonar a tabela EMPLOYEES do SCHEMA HR, coletar as estat\u00edsticas sem gerar o histograma na coluna JOB_ID que ser\u00e1 utilizada na cl\u00e1usula WHERE da consulta.<\/span><\/p>\n<p>&nbsp;<\/p>\n<div class=\"codecolorer-container php default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;width:800px;height:520px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/><\/div><\/td><td><div class=\"php codecolorer\">SQL <span class=\"sy0\">&gt;<\/span> SELECT <span class=\"sy0\">*<\/span> FROM V<span class=\"re0\">$VERSION<\/span> where rownum <span class=\"sy0\">&lt;<\/span> <span class=\"nu0\">2<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nBANNER<br \/>\n<span class=\"sy0\">--------------------------------------------------------------------------------<\/span><br \/>\nOracle Database 11g Enterprise Edition Release 11<span class=\"sy0\">.<\/span>2<span class=\"sy0\">.<\/span>0<span class=\"sy0\">.<\/span>4<span class=\"sy0\">.<\/span>0 <span class=\"sy0\">-<\/span> 64bit Production<br \/>\n<br \/>\n<span class=\"nu0\">1<\/span> linha selecionada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span> create table employees <span class=\"kw1\">as<\/span> select <span class=\"sy0\">*<\/span> from hr<span class=\"sy0\">.<\/span>employees<span class=\"sy0\">;<\/span><br \/>\n<br \/>\nTabela criada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span> CREATE UNIQUE INDEX EMP_EMP_ID_PK ON EMPLOYEES <span class=\"br0\">&#40;<\/span>EMPLOYEE_ID<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n\u00cdndice criado<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span> <a href=\"http:\/\/www.php.net\/exec\"><span class=\"kw3\">exec<\/span><\/a> dbms_stats<span class=\"sy0\">.<\/span>gather_table_stats<span class=\"br0\">&#40;<\/span>ownname<span class=\"sy0\">=&gt;<\/span> USER<span class=\"sy0\">,<\/span> tabname<span class=\"sy0\">=&gt;<\/span> <span class=\"st_h\">'EMPLOYEES'<\/span><span class=\"sy0\">,<\/span> cascade<span class=\"sy0\">=&gt;<\/span> <span class=\"kw4\">true<\/span><span class=\"sy0\">,<\/span> method_opt<span class=\"sy0\">=&gt;<\/span> <span class=\"st_h\">'FOR ALL COLUMNS SIZE AUTO'<\/span><span class=\"sy0\">,<\/span>force<span class=\"sy0\">=&gt;<\/span> <span class=\"kw4\">true<\/span><span class=\"sy0\">,<\/span>degree<span class=\"sy0\">=&gt;<\/span> <span class=\"nu0\">16<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nProcedimento PL<span class=\"sy0\">\/<\/span>SQL conclu\u00ed<span class=\"kw1\">do<\/span> com sucesso<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>&nbsp;<\/p>\n<h3 style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Executar a consulta<\/span><\/h3>\n<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Agora vamos executar uma consulta na tabela criada e listar o plano de execu\u00e7\u00e3o utilizado pelo Otimizador<\/span><\/p>\n<p>&nbsp;<\/p>\n<div class=\"codecolorer-container php default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;width:800px;height:520px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/>28<br \/>29<br \/>30<br \/>31<br \/>32<br \/>33<br \/>34<br \/>35<br \/>36<br \/>37<br \/>38<br \/>39<br \/>40<br \/>41<br \/>42<br \/>43<br \/>44<br \/>45<br \/>46<br \/>47<br \/>48<br \/>49<br \/>50<br \/>51<br \/>52<br \/>53<br \/>54<br \/>55<br \/>56<br \/>57<br \/>58<br \/>59<br \/>60<br \/>61<br \/>62<br \/>63<br \/>64<br \/>65<br \/>66<br \/>67<br \/>68<br \/>69<br \/>70<br \/>71<br \/>72<br \/>73<br \/>74<br \/>75<br \/>76<br \/>77<br \/>78<br \/>79<br \/>80<br \/>81<br \/>82<br \/>83<br \/>84<br \/>85<br \/>86<br \/>87<br \/><\/div><\/td><td><div class=\"php codecolorer\">SQL <span class=\"sy0\">&gt;<\/span> ALTER SESSION SET statistics_level<span class=\"sy0\">=<\/span>ALL<span class=\"sy0\">;<\/span><br \/>\n<br \/>\nSess\u00e3o alterada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><br \/>\nSQL <span class=\"sy0\">&gt;<\/span> select <span class=\"coMULTI\">\/* dbtw001 &nbsp;*\/<\/span> EMPLOYEE_ID<span class=\"sy0\">,<\/span> LAST_NAME<span class=\"sy0\">,<\/span> DEPARTMENT_ID<span class=\"sy0\">,<\/span> JOB_ID<br \/>\n&nbsp; <span class=\"nu0\">2<\/span> &nbsp; &nbsp;from employees<br \/>\n&nbsp; <span class=\"nu0\">3<\/span> &nbsp; where JOB_ID <span class=\"sy0\">=<\/span> <span class=\"st_h\">'AD_ASST'<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nEMPLOYEE_ID LAST_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DEPARTMENT_ID JOB_ID<br \/>\n<span class=\"sy0\">-----------<\/span> <span class=\"sy0\">-------------------------<\/span> <span class=\"sy0\">-------------<\/span> <span class=\"sy0\">----------<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"nu0\">200<\/span> Whalen &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"nu0\">10<\/span> AD_ASST<br \/>\n<br \/>\n<span class=\"nu0\">1<\/span> linha selecionada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><br \/>\nSQL <span class=\"sy0\">&gt;<\/span> column sql_id new_value m_sql_id<br \/>\nSQL <span class=\"sy0\">&gt;<\/span> column child_number new_value m_child_no<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><br \/>\nSQL <span class=\"sy0\">&gt;<\/span> SELECT sql_id<span class=\"sy0\">,<\/span> child_number<br \/>\n&nbsp; <span class=\"nu0\">2<\/span> &nbsp; &nbsp;FROM v<span class=\"re0\">$sql<\/span><br \/>\n&nbsp; <span class=\"nu0\">3<\/span> &nbsp; WHERE sql_text LIKE <span class=\"st_h\">'%dbtw001%'<\/span><br \/>\n&nbsp; <span class=\"nu0\">4<\/span> &nbsp; &nbsp; AND sql_text NOT LIKE <span class=\"st_h\">'%v$sql%'<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nSQL_ID &nbsp; &nbsp; &nbsp; &nbsp;CHILD_NUMBER<br \/>\n<span class=\"sy0\">-------------<\/span> <span class=\"sy0\">------------<\/span><br \/>\n4aukqvu2t0yvh &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class=\"nu0\">0<\/span><br \/>\n<br \/>\n<span class=\"nu0\">1<\/span> linha selecionada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><br \/>\nSQL <span class=\"sy0\">&gt;<\/span><br \/>\nSQL <span class=\"sy0\">&gt;<\/span> SELECT <span class=\"sy0\">*<\/span><br \/>\n&nbsp; <span class=\"nu0\">2<\/span> &nbsp; &nbsp;FROM TABLE <span class=\"br0\">&#40;<\/span>dbms_xplan<span class=\"sy0\">.<\/span>display_cursor <span class=\"br0\">&#40;<\/span><span class=\"st_h\">'&amp;m_sql_id'<\/span><span class=\"sy0\">,&amp;<\/span>m_child_no<span class=\"sy0\">,<\/span><span class=\"st_h\">'ALLSTATS LAST'<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nPLAN_TABLE_OUTPUT<br \/>\n<span class=\"sy0\">-------------------------------------------------------------------------------------------<\/span><br \/>\nSQL_ID &nbsp;4aukqvu2t0yvh<span class=\"sy0\">,<\/span> child number <span class=\"nu0\">0<\/span><br \/>\n<span class=\"sy0\">-------------------------------------<\/span><br \/>\nselect <span class=\"coMULTI\">\/* dbtw001 &nbsp;*\/<\/span> EMPLOYEE_ID<span class=\"sy0\">,<\/span> LAST_NAME<span class=\"sy0\">,<\/span> DEPARTMENT_ID<span class=\"sy0\">,<\/span> JOB_ID<br \/>\nfrom employees &nbsp;where JOB_ID <span class=\"sy0\">=<\/span> <span class=\"sy0\">:<\/span><span class=\"st0\">&quot;SYS_B_0&quot;<\/span><br \/>\n<br \/>\nPlan <a href=\"http:\/\/www.php.net\/hash\"><span class=\"kw3\">hash<\/span><\/a> value<span class=\"sy0\">:<\/span> <span class=\"nu0\">1445457117<\/span><br \/>\n<br \/>\n<span class=\"sy0\">-----------------------------------------------------------------------------------------<\/span><br \/>\n<span class=\"sy0\">|<\/span> Id &nbsp;<span class=\"sy0\">|<\/span> Operation &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sy0\">|<\/span> Name &nbsp; &nbsp; &nbsp;<span class=\"sy0\">|<\/span> Starts <span class=\"sy0\">|<\/span> E<span class=\"sy0\">-<\/span>Rows <span class=\"sy0\">|<\/span> A<span class=\"sy0\">-<\/span>Rows <span class=\"sy0\">|<\/span> &nbsp; A<span class=\"sy0\">-<\/span><a href=\"http:\/\/www.php.net\/time\"><span class=\"kw3\">Time<\/span><\/a> &nbsp; <span class=\"sy0\">|<\/span> Buffers <span class=\"sy0\">|<\/span><br \/>\n<span class=\"sy0\">-----------------------------------------------------------------------------------------<\/span><br \/>\n<span class=\"sy0\">|<\/span> &nbsp; <span class=\"nu0\">0<\/span> <span class=\"sy0\">|<\/span> SELECT STATEMENT &nbsp;<span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp; &nbsp;<span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">|<\/span><span class=\"nu8\">00<\/span><span class=\"sy0\">:<\/span><span class=\"nu8\">00<\/span><span class=\"sy0\">:<\/span><span class=\"nu19\">00.01<\/span> <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp; <span class=\"nu0\">4<\/span> <span class=\"sy0\">|<\/span><br \/>\n<span class=\"sy0\">|*<\/span> &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">|<\/span> &nbsp;TABLE ACCESS FULL<span class=\"sy0\">|<\/span> EMPLOYEES <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp;<span class=\"nu0\">6<\/span> <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">|<\/span><span class=\"nu8\">00<\/span><span class=\"sy0\">:<\/span><span class=\"nu8\">00<\/span><span class=\"sy0\">:<\/span><span class=\"nu19\">00.01<\/span> <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp; <span class=\"nu0\">4<\/span> <span class=\"sy0\">|<\/span><br \/>\n<span class=\"sy0\">-----------------------------------------------------------------------------------------<\/span><br \/>\n<br \/>\nPredicate Information <span class=\"br0\">&#40;<\/span>identified by operation id<span class=\"br0\">&#41;<\/span><span class=\"sy0\">:<\/span><br \/>\n<span class=\"sy0\">---------------------------------------------------<\/span><br \/>\n<br \/>\n&nbsp; &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">-<\/span> filter<span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;JOB_ID&quot;<\/span><span class=\"sy0\">=:<\/span>SYS_B_0<span class=\"br0\">&#41;<\/span><br \/>\n<br \/>\n<br \/>\n<span class=\"nu0\">19<\/span> linhas selecionadas<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span> column <span class=\"st0\">&quot;Num. linhas na tabela&quot;<\/span> new_value num_lin_tot<br \/>\nSQL <span class=\"sy0\">&gt;<\/span> column <span class=\"st0\">&quot;Num. linhas distintas&quot;<\/span> new_value num_lin_dist<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><br \/>\nSQL <span class=\"sy0\">&gt;<\/span> select <a href=\"http:\/\/www.php.net\/count\"><span class=\"kw3\">count<\/span><\/a><span class=\"br0\">&#40;<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span> <span class=\"st0\">&quot;Num. linhas na tabela&quot;<\/span> from employees<span class=\"sy0\">;<\/span><br \/>\n<br \/>\nNum<span class=\"sy0\">.<\/span> linhas na tabela<br \/>\n<span class=\"sy0\">---------------------<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"nu0\">107<\/span><br \/>\n<br \/>\n<span class=\"nu0\">1<\/span> linha selecionada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span> select <a href=\"http:\/\/www.php.net\/count\"><span class=\"kw3\">count<\/span><\/a><span class=\"br0\">&#40;<\/span>distinct<span class=\"br0\">&#40;<\/span>JOB_ID<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"st0\">&quot;Num. linhas distintas&quot;<\/span> from employees<span class=\"sy0\">;<\/span><br \/>\n<br \/>\nNum<span class=\"sy0\">.<\/span> linhas distintas<br \/>\n<span class=\"sy0\">---------------------<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class=\"nu0\">19<\/span><br \/>\n<br \/>\n<span class=\"nu0\">1<\/span> linha selecionada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span> select <a href=\"http:\/\/www.php.net\/round\"><span class=\"kw3\">round<\/span><\/a><span class=\"br0\">&#40;<\/span><span class=\"sy0\">&amp;<\/span>num_lin_tot<span class=\"sy0\">\/&amp;<\/span>num_lin_dist<span class=\"br0\">&#41;<\/span> CARDINALIDADE from dual<span class=\"sy0\">;<\/span><br \/>\n<br \/>\nCARDINALIDADE<br \/>\n<span class=\"sy0\">-------------<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"nu0\">6<\/span><br \/>\n<br \/>\n<span class=\"nu0\">1<\/span> linha selecionada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">No plano de execu\u00e7\u00e3o verificamos que o Otimizador estimou que a cardinalidade da tabela &#8220;EMPLOYEES&#8221; seriam 6 registros (E-ROWS), quando na verdade foi 1 registro (A-ROWS).<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">O Otimizador calculou a cardinalidade como 6 pois ele dividiu a quantidade total de registros (107) pelo n\u00famero de valores distintos na coluna JOB_ID (19).<\/span><\/p>\n<h3 style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Coletar as estat\u00edsticas com histograma<\/span><\/h3>\n<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Para gerar histogramas em todas as colunas que possuem repeti\u00e7\u00e3o de dados n\u00e3o uniforme na tabela \u00e9 necess\u00e1rio utilizar a cl\u00e1usula &#8220;method_opt=&gt; &#8216;FOR ALL COLUMNS SIZE SKEWONLY'&#8221;.<\/span><\/p>\n<p>&nbsp;<\/p>\n<div class=\"codecolorer-container php default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;width:800px;height:520px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/><\/div><\/td><td><div class=\"php codecolorer\">SQL <span class=\"sy0\">&gt;<\/span> SELECT column_name<span class=\"sy0\">,<\/span> num_distinct<span class=\"sy0\">,<\/span> histogram<br \/>\n&nbsp; <span class=\"nu0\">2<\/span> &nbsp; &nbsp;FROM user_tab_col_statistics<br \/>\n&nbsp; <span class=\"nu0\">3<\/span> &nbsp; WHERE table_name <span class=\"sy0\">=<\/span> <span class=\"st_h\">'EMPLOYEES'<\/span><br \/>\n&nbsp; <span class=\"nu0\">4<\/span> &nbsp; &nbsp; AND column_name <span class=\"sy0\">=<\/span> <span class=\"st_h\">'JOB_ID'<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nColuna &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NUM_DISTINCT HISTOGRAM<br \/>\n<span class=\"sy0\">--------------------<\/span> <span class=\"sy0\">------------<\/span> <span class=\"sy0\">---------------<\/span><br \/>\nJOB_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"nu0\">19<\/span> NONE<br \/>\n<br \/>\n<span class=\"nu0\">1<\/span> linha selecionada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span> <a href=\"http:\/\/www.php.net\/exec\"><span class=\"kw3\">exec<\/span><\/a> dbms_stats<span class=\"sy0\">.<\/span>gather_table_stats<span class=\"br0\">&#40;<\/span>ownname<span class=\"sy0\">=&gt;<\/span> USER<span class=\"sy0\">,<\/span> tabname<span class=\"sy0\">=&gt;<\/span> <span class=\"st_h\">'EMPLOYEES'<\/span><span class=\"sy0\">,<\/span> cascade<span class=\"sy0\">=&gt;<\/span> <span class=\"kw4\">true<\/span><span class=\"sy0\">,<\/span> method_opt<span class=\"sy0\">=&gt;<\/span> <span class=\"st_h\">'FOR ALL COLUMNS SIZE SKEWONLY'<\/span><span class=\"sy0\">,<\/span>force<span class=\"sy0\">=&gt;<\/span> <span class=\"kw4\">true<\/span><span class=\"sy0\">,<\/span>degree<span class=\"sy0\">=&gt;<\/span> <span class=\"nu0\">16<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nProcedimento PL<span class=\"sy0\">\/<\/span>SQL conclu\u00ed<span class=\"kw1\">do<\/span> com sucesso<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span> SELECT column_name<span class=\"sy0\">,<\/span> num_distinct<span class=\"sy0\">,<\/span> histogram<br \/>\n&nbsp; <span class=\"nu0\">2<\/span> &nbsp; &nbsp;FROM user_tab_col_statistics<br \/>\n&nbsp; <span class=\"nu0\">3<\/span> &nbsp; WHERE table_name <span class=\"sy0\">=<\/span> <span class=\"st_h\">'EMPLOYEES'<\/span><br \/>\n&nbsp; <span class=\"nu0\">4<\/span> &nbsp; &nbsp; AND column_name <span class=\"sy0\">=<\/span> <span class=\"st_h\">'JOB_ID'<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nColuna &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NUM_DISTINCT HISTOGRAM<br \/>\n<span class=\"sy0\">--------------------<\/span> <span class=\"sy0\">------------<\/span> <span class=\"sy0\">---------------<\/span><br \/>\nJOB_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"nu0\">19<\/span> FREQUENCY<br \/>\n<br \/>\n<span class=\"nu0\">1<\/span> linha selecionada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>&nbsp;<\/p>\n<h2 style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Executar a consulta novamente<\/span><\/h2>\n<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Finalmente vamos executar a consulta na tabela com os histogramas gerados pelo pacote DBMS_STATS e verificar a qualidade da cardinalidade estimada pelo Otimizador.<\/span><\/p>\n<p>&nbsp;<\/p>\n<div class=\"codecolorer-container php default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;width:800px;height:520px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/>28<br \/>29<br \/>30<br \/>31<br \/>32<br \/>33<br \/>34<br \/>35<br \/>36<br \/>37<br \/>38<br \/>39<br \/>40<br \/>41<br \/>42<br \/>43<br \/>44<br \/>45<br \/>46<br \/>47<br \/>48<br \/>49<br \/>50<br \/>51<br \/>52<br \/>53<br \/>54<br \/>55<br \/>56<br \/>57<br \/>58<br \/>59<br \/>60<br \/><\/div><\/td><td><div class=\"php codecolorer\">SQL <span class=\"sy0\">&gt;<\/span> ALTER SESSION SET statistics_level<span class=\"sy0\">=<\/span>ALL<span class=\"sy0\">;<\/span><br \/>\n<br \/>\nSess\u00e3o alterada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><br \/>\nSQL <span class=\"sy0\">&gt;<\/span> select <span class=\"coMULTI\">\/* dbtw002 &nbsp;*\/<\/span> EMPLOYEE_ID<span class=\"sy0\">,<\/span> LAST_NAME<span class=\"sy0\">,<\/span> DEPARTMENT_ID<span class=\"sy0\">,<\/span> JOB_ID<br \/>\n&nbsp; <span class=\"nu0\">2<\/span> &nbsp; &nbsp;from employees<br \/>\n&nbsp; <span class=\"nu0\">3<\/span> &nbsp; where JOB_ID <span class=\"sy0\">=<\/span> <span class=\"st_h\">'AD_ASST'<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nEMPLOYEE_ID LAST_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DEPARTMENT_ID JOB_ID<br \/>\n<span class=\"sy0\">-----------<\/span> <span class=\"sy0\">-------------------------<\/span> <span class=\"sy0\">-------------<\/span> <span class=\"sy0\">----------<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"nu0\">200<\/span> Whalen &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"nu0\">10<\/span> AD_ASST<br \/>\n<br \/>\n<span class=\"nu0\">1<\/span> linha selecionada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><br \/>\nSQL <span class=\"sy0\">&gt;<\/span> column sql_id new_value m_sql_id<br \/>\nSQL <span class=\"sy0\">&gt;<\/span> column child_number new_value m_child_no<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><br \/>\nSQL <span class=\"sy0\">&gt;<\/span> SELECT sql_id<span class=\"sy0\">,<\/span> child_number<br \/>\n&nbsp; <span class=\"nu0\">2<\/span> &nbsp; &nbsp;FROM v<span class=\"re0\">$sql<\/span><br \/>\n&nbsp; <span class=\"nu0\">3<\/span> &nbsp; WHERE sql_text LIKE <span class=\"st_h\">'%dbtw002%'<\/span><br \/>\n&nbsp; <span class=\"nu0\">4<\/span> &nbsp; &nbsp; AND sql_text NOT LIKE <span class=\"st_h\">'%v$sql%'<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nSQL_ID &nbsp; &nbsp; &nbsp; &nbsp;CHILD_NUMBER<br \/>\n<span class=\"sy0\">-------------<\/span> <span class=\"sy0\">------------<\/span><br \/>\ndv574duqu8q1w &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class=\"nu0\">0<\/span><br \/>\n<br \/>\n<span class=\"nu0\">1<\/span> linha selecionada<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><br \/>\nSQL <span class=\"sy0\">&gt;<\/span><br \/>\nSQL <span class=\"sy0\">&gt;<\/span> SELECT <span class=\"sy0\">*<\/span><br \/>\n&nbsp; <span class=\"nu0\">2<\/span> &nbsp; &nbsp;FROM TABLE <span class=\"br0\">&#40;<\/span>dbms_xplan<span class=\"sy0\">.<\/span>display_cursor <span class=\"br0\">&#40;<\/span><span class=\"st_h\">'&amp;m_sql_id'<\/span><span class=\"sy0\">,&amp;<\/span>m_child_no<span class=\"sy0\">,<\/span><span class=\"st_h\">'ALLSTATS LAST'<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nPLAN_TABLE_OUTPUT<br \/>\n<span class=\"sy0\">-----------------------------------------------------------------------------------------<\/span><br \/>\nSQL_ID &nbsp;dv574duqu8q1w<span class=\"sy0\">,<\/span> child number <span class=\"nu0\">0<\/span><br \/>\n<span class=\"sy0\">-------------------------------------<\/span><br \/>\nselect <span class=\"coMULTI\">\/* dbtw002 &nbsp;*\/<\/span> EMPLOYEE_ID<span class=\"sy0\">,<\/span> LAST_NAME<span class=\"sy0\">,<\/span> DEPARTMENT_ID<span class=\"sy0\">,<\/span> JOB_ID<br \/>\nfrom employees &nbsp;where JOB_ID <span class=\"sy0\">=<\/span> <span class=\"sy0\">:<\/span><span class=\"st0\">&quot;SYS_B_0&quot;<\/span><br \/>\n<br \/>\nPlan <a href=\"http:\/\/www.php.net\/hash\"><span class=\"kw3\">hash<\/span><\/a> value<span class=\"sy0\">:<\/span> <span class=\"nu0\">1445457117<\/span><br \/>\n<br \/>\n<span class=\"sy0\">-----------------------------------------------------------------------------------------<\/span><br \/>\n<span class=\"sy0\">|<\/span> Id &nbsp;<span class=\"sy0\">|<\/span> Operation &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sy0\">|<\/span> Name &nbsp; &nbsp; &nbsp;<span class=\"sy0\">|<\/span> Starts <span class=\"sy0\">|<\/span> E<span class=\"sy0\">-<\/span>Rows <span class=\"sy0\">|<\/span> A<span class=\"sy0\">-<\/span>Rows <span class=\"sy0\">|<\/span> &nbsp; A<span class=\"sy0\">-<\/span><a href=\"http:\/\/www.php.net\/time\"><span class=\"kw3\">Time<\/span><\/a> &nbsp; <span class=\"sy0\">|<\/span> Buffers <span class=\"sy0\">|<\/span><br \/>\n<span class=\"sy0\">-----------------------------------------------------------------------------------------<\/span><br \/>\n<span class=\"sy0\">|<\/span> &nbsp; <span class=\"nu0\">0<\/span> <span class=\"sy0\">|<\/span> SELECT STATEMENT &nbsp;<span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp; &nbsp;<span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">|<\/span><span class=\"nu8\">00<\/span><span class=\"sy0\">:<\/span><span class=\"nu8\">00<\/span><span class=\"sy0\">:<\/span><span class=\"nu19\">00.01<\/span> <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp; <span class=\"nu0\">4<\/span> <span class=\"sy0\">|<\/span><br \/>\n<span class=\"sy0\">|*<\/span> &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">|<\/span> &nbsp;TABLE ACCESS FULL<span class=\"sy0\">|<\/span> EMPLOYEES <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">|<\/span><span class=\"nu8\">00<\/span><span class=\"sy0\">:<\/span><span class=\"nu8\">00<\/span><span class=\"sy0\">:<\/span><span class=\"nu19\">00.01<\/span> <span class=\"sy0\">|<\/span> &nbsp; &nbsp; &nbsp; <span class=\"nu0\">4<\/span> <span class=\"sy0\">|<\/span><br \/>\n<span class=\"sy0\">-----------------------------------------------------------------------------------------<\/span><br \/>\n<br \/>\nPredicate Information <span class=\"br0\">&#40;<\/span>identified by operation id<span class=\"br0\">&#41;<\/span><span class=\"sy0\">:<\/span><br \/>\n<span class=\"sy0\">---------------------------------------------------<\/span><br \/>\n<br \/>\n&nbsp; &nbsp;<span class=\"nu0\">1<\/span> <span class=\"sy0\">-<\/span> filter<span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;JOB_ID&quot;<\/span><span class=\"sy0\">=:<\/span>SYS_B_0<span class=\"br0\">&#41;<\/span><br \/>\n<br \/>\n<br \/>\n<span class=\"nu0\">19<\/span> linhas selecionadas<span class=\"sy0\">.<\/span><br \/>\n<br \/>\nSQL <span class=\"sy0\">&gt;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Analisando o plano de execu\u00e7\u00e3o acima verificamos que a cardinalidade estimada pelo Otimizador foi perfeita (1 registro), igual a quantidade de registros lidos (E-ROWS = A-ROWS).<\/span><\/p>\n<h2 style=\"text-align: justify;\"><span style=\"font-size: 14pt;\">Conclus\u00e3o<\/span><\/h2>\n<p style=\"text-align: justify;\"><span style=\"font-size: 12pt;\">Nesse artigo verificamos na pr\u00e1tica a import\u00e2ncia do histograma para que o Otimizador consiga realizar estimativas de cardinalidade com precis\u00e3o, o gerenciamento da coleta de estat\u00edsticas \u00e9 fundamental para garantir a cria\u00e7\u00e3o de histogramas em colunas de tabelas que possuem repeti\u00e7\u00e3o de dados n\u00e3o uniforme e s\u00e3o mencionadas na cl\u00e1usula WHERE das instru\u00e7\u00f5es SQL. O pacote DBMS_STATS pode e deve ser utilizado para fazer os ajustes necess\u00e1rios no processo de coleta de estat\u00edsticas de acordo com as caracter\u00edsticas dos dados e como eles s\u00e3o atualizados.<\/span><\/p>\n<h2 style=\"text-align: justify;\"><span style=\"font-size: 14pt;\">Refer\u00eancias<\/span><\/h2>\n<p><strong><span style=\"font-size: 12pt;\"><a href=\"http:\/\/gavinsoorma.com\/wp-content\/uploads\/2011\/03\/top_tips_for_optimal_sql_execution.pdf\" target=\"_blank\">http:\/\/gavinsoorma.com\/wp-content\/uploads\/2011\/03\/top_tips_for_optimal_sql_execution.pdf<\/a><\/span><\/strong><\/p>\n<p><strong><span style=\"font-size: 12pt;\"><a href=\"https:\/\/docs.oracle.com\/database\/121\/ARPLS\/d_stats.htm#ARPLS68491\" target=\"_blank\">https:\/\/docs.oracle.com\/database\/121\/ARPLS\/d_stats.htm#ARPLS68491<\/a><\/span><\/strong><\/p>\n<p>&nbsp;<br \/>\n&nbsp;<br \/>\n<a href=\"http:\/\/dbtimewizard.com.br\/treinamento\/\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-1255\" src=\"http:\/\/dbtimewizard.com.br\/blog\/wp-content\/uploads\/2018\/10\/promo_cur02.jpg\" alt=\"Promo-D75L\" width=\"330\" height=\"242\" \/><\/a><\/p>\n<p><a href=\"https:\/\/youtu.be\/l6OphhTle9I\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-1215\" src=\"http:\/\/dbtimewizard.com.br\/wp-content\/uploads\/2018\/01\/video-02-300x168.jpg\" alt=\"video-02\" width=\"330\" height=\"242\" \/><\/a><br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>No artigo &#8220;Por que o Otimizador criou um plano de execu\u00e7\u00e3o ineficiente?&#8221; elencamos algumas condi\u00e7\u00f5es que levam o Otimizador a gerar um plano de execu\u00e7\u00e3o ineficiente, neste artigo vamos abordar com mais detalhes um desses t\u00f3picos, como a repeti\u00e7\u00e3o de dados n\u00e3o uniformes em uma coluna da tabela podem influenciar de maneira negativa o Otimizador. &nbsp; &nbsp; &nbsp; Repeti\u00e7\u00e3o de<\/p>\n","protected":false},"author":2,"featured_media":992,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[71],"tags":[129,128,6,42,163,162,161,10],"class_list":["post-991","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-estatisticas","tag-cardinalidade","tag-cardinality","tag-cbo","tag-cost-base-optimizer","tag-dbms_stats","tag-histogramas","tag-histograms","tag-otimizador"],"aioseo_notices":[],"_links":{"self":[{"href":"http:\/\/dbtimewizard.com.br\/blog\/wp-json\/wp\/v2\/posts\/991","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/dbtimewizard.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/dbtimewizard.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/dbtimewizard.com.br\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/dbtimewizard.com.br\/blog\/wp-json\/wp\/v2\/comments?post=991"}],"version-history":[{"count":16,"href":"http:\/\/dbtimewizard.com.br\/blog\/wp-json\/wp\/v2\/posts\/991\/revisions"}],"predecessor-version":[{"id":2059,"href":"http:\/\/dbtimewizard.com.br\/blog\/wp-json\/wp\/v2\/posts\/991\/revisions\/2059"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/dbtimewizard.com.br\/blog\/wp-json\/wp\/v2\/media\/992"}],"wp:attachment":[{"href":"http:\/\/dbtimewizard.com.br\/blog\/wp-json\/wp\/v2\/media?parent=991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/dbtimewizard.com.br\/blog\/wp-json\/wp\/v2\/categories?post=991"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/dbtimewizard.com.br\/blog\/wp-json\/wp\/v2\/tags?post=991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}