O processo de Tuning de instruções SQL não é uma tarefa fácil, existem ótimas ferramentas para auxiliar nesse trabalho, aquelas que requerem investimento normalmente não estão a nossa disposição nos ambientes onde trabalhamos. Neste artigo vamos listar 9 ferramentas de uso gratuito que podem ser baixadas e utilizadas sem custo,…
Qual é o segredo da alta performace do Exadata?
Com o crescimento dos negócios de uma empresa e a automatização de seus processos, aumenta o volume de dados que precisam ser armazenados, esse aumento na quantidade de dados acaba muitas vezes prejudicando o tempo de resposta das aplicações. Se a sua empresa possui Banco de dados com tamanhos em Terabytes, os usuários das aplicações reclamam de performance, você já realizou um bom trabalho de tuning na sua plataforma e o problema de performance tem impacto nos negócios da empresa, você deveria considerar a possibilidade de utilizar a solução Exadata.
Neste artigo vamos falar um pouco sobre a arquitetura do Exadata e porque sua performance é muito superior às arquiteturas tradicionais.
Arquiteturas Tradicionais
Numa arquitetura tradicional normalmente instalamos o Banco de dados Oracle (Instâncias Lógicas) em servidores com sistema operacional Unix-like ou Microsoft e os dados são armazenados em servidores Storage. Nessa arquitetura os dados solicitados por uma consulta precisam ser transferidos do Storage para os servidores de banco, onde são tratados pelas instâncias para gerar o resultado final da consulta, quando essa consulta precisa acessar tabelas com grandes volumes de dados a transferência de dados torna-se um gargalo, pois ela é feita pela rede.
Arquitetura Exadata
A arquitetura do Exadata foi concebida para resolver esse problema de gargalo de transferência de dados do Storage para o servidor de Banco, para atingir esse objetivo a Oracle utilizou duas estratégias:
1. Diminuir a quantidade de dados que são transferidos do Storage para o Banco.
2. Aumentar a velocidade de transferência de dados entre Storage e o Banco.
Para diminuir a quantidade de dados transferidos do Storage para o Banco foi necessário agregar algumas funções do banco de dados ao Storage, com isso uma parte das tarefas realizadas durante a execução da instrução SQL passaram a ser executadas no servidor Storage por processos “Cell offloading”. Na geração X5-2 os Servidores Storage do Exadata realizam 7 funções que numa arquitetura tradicional seriam realizadas pelo servidor de banco de dados, as duas funções que mais contribuem para a redução da quantidade de dados que são transferidos do Storage para o banco de dados são:
1. Column Projection: O servidor Storage envia para o banco somente as colunas que fazem parte da lista da clausula “SELECT”, ou seja, se a tabela acessada possui 50 colunas e a consulta tem somente 5 colunas na clausula “SELECT”, somente essas 5 colunas serão transferidas do Storage para o Banco.
2. Predicate Filtering: O servidor Storage restringe os registros que serão enviados ao servidor de banco baseado nos filtros da claúsula WHERE da instrução SQL, numa arquitetura tradicional os registros que não são filtrados por um índice são enviados para o Buffer Cache onde são filtrados pelo banco.
Ajudo DBAs e analistas de sistema a se destacarem em suas empresas
e obter um crescimento mais acelerado em suas carreiras, quer saber mais click no link abaixo:
Para aumentar a velocidade de transferência de dados entre o Storage e o Banco, a arquitetura Exadata dispõem de 3 recursos:
1. Uma rede InfiniBand que prove uma capacidade de transferência de dados do Storage para o Banco de 40 Gb/Sec, numa arquitetura tradicional a melhor opção disponível é uma rede Fiber Channel que prove uma capacidade de transferência de 16 Gb/sec.
2. Os servidores de Storage dispõem de áreas de memória flash chamadas ‘Cell Flash Cache’ que diminuem a necessidade de acesso mecânico aos discos aumentando a velocidade de acesso aos dados.
3. A função Storage Index tambem contribui para o aumento da velocidade de transferência dos dados, pois diminui o numero de blocos físicos acessados para leitura dos dados no Storage.
Smart Scan
A arquitetura de Hardware do Exadata foi concebida para prover alta disponibilidade e alta performance, mas na parte de performance o destaque não esta no Hardware e sim no Software, as duas funções mencionadas acima que visam a redução do volume de dados transferidos do Storage para o Banco de dados são também conhecidas como “Smart Scan”, elas são as responsáveis pelo fantástico desempenho de performance do Exadata. Para demostrar isso vamos simular uma consulta no Exadata utilizando somente os recursos de Hardware e em seguida vamos executar a mesma consulta utilizando tambem o “Smart Scan”.
Para realizar esta simulação vamos criar uma tabela de 5 GB de dados e não vamos utilizar índice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | SQL > SELECT * FROM V$VERSION where rownum < 2; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production SQL > create table dbtw01 as 2 select 'DBTimeWizard - Performance and Tuning' as produto, 3 mod(rownum,5) as codigo, 4 mod(rownum,1000) as cliente_id , 5 5000 as total_vendas, 6 trunc(sysdate - 9999 + mod(rownum,10000)) as data_venda 7 from dual connect by level<=2e7; Table created. SQL > alter table dbtw01 nologging; Table altered. SQL > SQL > insert /*+ append */ into dbtw01 select * from dbtw01; 20000000 rows created. SQL > SQL > commit; Commit complete. SQL > insert /*+ append */ into dbtw01 select * from dbtw01; 40000000 rows created. SQL > SQL > commit; Commit complete. SQL > SQL > select round(bytes/1024/1024/1024,1) as "Tamanho GB" 2 from user_segments 3 where segment_name = 'DBTW01'; Tamanho GB ---------- 5.1 SQL > SQL > exec dbms_stats.gather_table_stats(ownname=> USER, tabname=> 'DBTW01', cascade=> true, method_opt=> 'FOR ALL COLUMNS SIZE SKEWONLY'); PL/SQL procedure successfully completed. SQL > alter table dbtw01 logging; Table altered. SQL > SQL > select count(1) from DBTW01; COUNT(1) ---------- 80000000 SQL > |
Simulação sem Smart Scan
Para desativar o Smart Scan vamos utilizar o parâmetro “cell_offload_processing=false”, e para garantir que o resultado da consulta não seja afetado por dados armazenados no buffer do banco de dados vamos executar um comando para limpar o Buffer Cache.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | SQL > alter system flush buffer_cache; System altered. SQL > SQL > alter session set cell_offload_processing=false; Session altered. SQL > SQL > ALTER SESSION SET statistics_level=ALL; Session altered. SQL > SQL > select /* NO_SMART_SCAN */ count(*) from DBTW01 where codigo=1; COUNT(*) ---------- 16000000 1 row selected. SQL > column sql_id new_value m_sql_id SQL > column child_number new_value m_child_no SQL > SQL > SELECT sql_id, child_number 2 FROM v$sql 3 WHERE sql_text LIKE '%NO_SMART_SCAN%' 4 AND sql_text NOT LIKE '%v$sql%'; SQL_ID CHILD_NUMBER ---------------- ------------ f60zgw6916cum 0 1 row selected. SQL > SQL > SQL > SELECT * 2 FROM TABLE (dbms_xplan.display_cursor ('&m_sql_id',&m_child_no,'typical iostats last')); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SQL_ID f60zgw6916cum, child number 0 ------------------------------------- select /* NO_SMART_SCAN */ count(*) from DBTW01 where codigo=:"SYS_B_0" Plan hash value: 2690647991 ---------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | Reads | ---------------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | 182K(100)| | 1 |00:00:14.80 | 671K| 671K| | 1 | SORT AGGREGATE | | 1 | 1 | 3 | | | 1 |00:00:14.80 | 671K| 671K| |* 2 | TABLE ACCESS STORAGE FULL| DBTW01 | 1 | 16M| 46M| 182K (1)| 00:36:35 | 16M|00:00:14.25 | 671K| 671K| ---------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("CODIGO"=:SYS_B_0) 19 rows selected. SQL > SQL > col SQL_TEXT for a80; SQL > select SQL_ID, 2 IO_CELL_OFFLOAD_ELIGIBLE_BYTES eligible, 3 IO_INTERCONNECT_BYTES actual, 4 sql_text 5 from v$sql 6 where SQL_ID in ('&m_sql_id'); SQL_ID ELIGIBLE ACTUAL SQL_TEXT ---------------- ---------- ---------- -------------------------------------------------------------------------------- f60zgw6916cum 0 5502640128 select /* NO_SMART_SCAN */ count(*) from DBTW01 where codigo=:"SYS_B_0" 1 row selected. SQL > SQL > select name, value 2 from v$mystat s, v$statname n 3 where s.statistic# = n.statistic# 4 and name like '%storage index%'; NAME VALUE ---------------------------------------------------------------- ---------- cell physical IO bytes saved by storage index 0 1 row selected. SQL > select round(bytes/1024/1024/1024,1) "Tamanho GB" from user_segments where segment_name = 'DBTW01'; Tamanho GB ---------- 5.1 1 row selected. SQL > select round(((671*1024)*8124)/1024/1024/1024,1) "Buffers GB" from dual; Buffers GB ---------- 5.2 1 row selected. SQL > |
Simulação com Smart Scan
Agora vamos ativar o Smart Scan utilizando o parâmetro “cell_offload_processing=true”, vamos limpar o Buffer Cache do banco e executar a mesma consulta novamente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | SQL > alter system flush buffer_cache; System altered. SQL > SQL > alter session set cell_offload_processing=true; Session altered. SQL > SQL > ALTER SESSION SET statistics_level=ALL; Session altered. SQL > select /* WITH_SMART_SCAN */ count(*) from DBTW01 where codigo=1; COUNT(*) ---------- 16000000 1 row selected. SQL > column sql_id new_value m_sql_id SQL > column child_number new_value m_child_no SQL > SQL > SELECT sql_id, child_number 2 FROM v$sql 3 WHERE sql_text LIKE '%WITH_SMART_SCAN%' 4 AND sql_text NOT LIKE '%v$sql%'; SQL_ID CHILD_NUMBER ---------------- ------------ 5tz9g9gga7asa 0 1 row selected. SQL > SQL > SQL > SELECT * 2 FROM TABLE (dbms_xplan.display_cursor ('&m_sql_id',&m_child_no,'typical iostats last')); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------------------------------------------------ SQL_ID 5tz9g9gga7asa, child number 0 ------------------------------------- select /* WITH_SMART_SCAN */ count(*) from DBTW01 where codigo=:"SYS_B_0" Plan hash value: 2690647991 ---------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | Reads | ---------------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | 182K(100)| | 1 |00:00:01.48 | 671K| 671K| | 1 | SORT AGGREGATE | | 1 | 1 | 3 | | | 1 |00:00:01.48 | 671K| 671K| |* 2 | TABLE ACCESS STORAGE FULL| DBTW01 | 1 | 16M| 46M| 182K (1)| 00:36:35 | 16M|00:00:00.95 | 671K| 671K| ---------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - storage("CODIGO"=:SYS_B_0) filter("CODIGO"=:SYS_B_0) 21 rows selected. SQL > SQL > select SQL_ID, 2 IO_CELL_OFFLOAD_ELIGIBLE_BYTES eligible, 3 IO_INTERCONNECT_BYTES actual, 4 100*(IO_CELL_OFFLOAD_ELIGIBLE_BYTES-IO_INTERCONNECT_BYTES)/IO_CELL_OFFLOAD_ELIGIBLE_BYTES "IO_SAVED_%", 5 sql_text 6 from v$sql 7 where SQL_ID in ('&m_sql_id'); SQL_ID ELIGIBLE ACTUAL IO_SAVED_% SQL_TEXT ---------------- ---------- ---------- ---------- -------------------------------------------------------------------------------- 5tz9g9gga7asa 5502566400 191218504 96.5249215 select /* WITH_SMART_SCAN */ count(*) from DBTW01 where codigo=:"SYS_B_0" 1 row selected. SQL > SQL > select name, value 2 from v$mystat s, v$statname n 3 where s.statistic# = n.statistic# 4 and name like '%storage index%'; NAME VALUE ---------------------------------------------------------------- ---------- cell physical IO bytes saved by storage index 0 1 row selected. SQL > |
Nesta segunda execução utilizando o Smart Scan podemos observar duas mudanças no plano de execução:
1. O tempo de duração da consulta caiu de 14,8 segundos para 1,5 segundos.
2. Na seção “Predicate Information” aparece a informação de que o filtro da claúsula WHERE foi aplicado a nível de Storage.
Conclusão
A alta performace do Exadata se deve ao fato de que todos os componentes de Hardware e Software foram desenhados para trabalhar juntos em perfeita sintonia, isso só foi possível pois todos os componentes da arquitetura Exadata pertencem ao mesmo fornecedor. Nessa arquitetura o componente mais importante na melhoria da performance é o Software Storage Cell que permitiu a execução de algumas funções do banco direto no servidor Storage eliminando muito trabalho desnecessário.
Referências
http://www.oracle.com/technetwork/database/exadata/exadata-technical-whitepaper-134575.pdf