Vou compartilhar com vocês um problema que ainda não consegui resolver e gostaria de, caso algum leitor saiba sobre o assunto e quiser compartilhar comentando, que me ajude por favor.
É mais ou menos o seguinte...
Na empresa onde sou DBA, utilizamos o banco Oracle 10G (release 10.2.0.3) e recentemente realizei uma alteração (para efeito de teste) do parâmetro CURSOR_SHARING. Alterei ele do seu valor default "EXACT" para o valor "SIMILAR".
Com a alteração, a taxa de hard parse diminuiu, e obtive um alto índice de reuso de query (ou scripts de modo geral).
Os testes estavam indo bem, quando és que surge uma consulta semelhante a seguinte:
select 'teste' as campo, 'Y' as tipo from dual
union
select 'teste1', 'N' from dual;
Com o parâmetro alterado, essa consulta foi interpretada como:
select '"SYS_B_0"' as campo, '"SYS_B_1"' as tipo from dual
union
select '"SYS_B_2"' as campo, '"SYS_B_3"' as tipo from dual;
Até então, tudo ocorreu conforme esperado, porém na aplicação que faz uso dessa base existia um teste conforme o indicado abaixo:
<%
'Código ASP
...
if cstr(rs.fields("tipo")) = "Y" then
<< fazer algo xcvdxwwx >>
else
<< fazer algo yzwyzee >>
end if
...
%>
Mesmo quando o retorno da consulta era = "Y", nunca entrava no if (e eu testei a consulta e ela realmente retornava Y).
Quando fui verificar o retorno pela aplicação, o campo "tipo" retornava "Y ¢¥¥├ò", ou seja, com um lixo após o valor.
Rodei a mesma consulta pelo sqlplus, e realmente o valor do retorno era apenas "Y".
Tentei alterar o provider da string de conexão do banco para ver se era esse o problema, mas o mesmo persistiu. O Oracle Client no servidor da aplicação é o 10G.
Não consegui entender o erro, e em todas as documentações e livros que pesquisei, os problemas oriundos da alteração desse parâmetro acarreta apenas em queda de performance (devido a por exemplo reutilizar um plano NÃO otimizado para uma consulta).
Esse problema inviabilizou a alteração que se comportara muito bem em outros aspectos.
Entendo que quando pensamos em reuso através de bind variables, associamos apenas à alterações dos parâmetros na seleção dos dados e não na projeção como é o caso citado.
Alguém tem alguma ideia sobre o que pode ser e se tem alguma alteração que possa ser feita para conseguir o ganho da performance dos "soft parses"?
Conto com o conhecimento de vocês!
Grato!!
Tentei ajuda também no fórum da Oracle:
ResponderExcluirhttps://forums.oracle.com/forums/thread.jspa?threadID=2505090&tstart=0
mas ainda não consegui uma resposta que solucionasse meu problema.
Pessoal,
ResponderExcluirCom a ajuda de amigos do setor de desenvolvimento de sistemas, consegui entender o problema. O que esta ocorrendo é que a aplicação utiliza um FRAMEWORK (com componentes e DLL's) para se conectar ao banco, e o mesmo tem um tratamento (não sei porque nem para que) na exibição da informação.
Nesse momento era inserido o código sujo no final do valor correto.
Nesse caso, é mais complexo se alterar a aplicação, inviabilizando de fato o uso do CURSOR_SHARING = SIMILAR.
Valeus!
Hmm... interessante...
ResponderExcluirPaliativo: Se seu aplicativo é usado por módulos v$session.module = nomemodulo ou se o procedimento que faz o teste (tipo = 'Y') for executado de um servidor especifico ou OSUSER ou username especifico ou outra informação relevante, vc pode criar uma trigger de logon no banco de dados ativando o parametro cursor_sharing na qual modulo != 'Moduloproblema' ou sys_context('USERENV','IP_ADDRESS') != '192.....' ou username ou osuser e assim por diante... imaginação é o limite..rsrs
forte abraço
Verdade, Wellington!!
ExcluirMas a maioria dos sistemas que acessam essa base fazem uso desse mesmo framework.
Uma das soluções que usamos foi alterar o CURSOR_SHARING em algumas sessions com o comando ALTER SESSION SET cursor_sharing='SIMILAR';
Isso foi realizado em alguns procedimentos que executavam no banco, porém a montagem dos scripts eram realizadas com query dinâmica.
Com a alteração realizada, melhorou muito a taxa de PARSE do banco.
Obrigado pela colaboração!
Outra dica: Se vc tiver o desenvolvimento do APP interno, vc pode facilmente contornar o problema alterando o parametro cursor_sharing para FORCE e nas querys com problemas vc pede para os desenvs adicionarem o hint: +cursor_sharing_exact
ResponderExcluirEx:
select /*+ cursor_sharing_exact */ 'teste' as campo, 'Y' as tipo
from dual
union
select /*+ cursor_sharing_exact */ 'teste1', 'N' from dual;
E pronto.. as query's com problema serão executadas como o parametro em "EXACT".
Lembrando que a Oracle recomenda que uso do cursor_sharing deveria ser temporário até que o código fosse alterado para utilização de BIND.
forte abraço
Boa dica!
ExcluirMas como são muitos sistemas e antigos, foi menos impactante realizar as alterações em pontos mais críticos de acordo com a equipe de sistemas. E como existem muitos procedimentos de banco nesses sistemas, foi uma alteração relativamente simples.
O uso de HINT é muito útil sim, mas nesse caso teria uma manutenção maior, além de poder impactar alguma "caixa preta" do sistema.
Mais uma vez, valeu pela colaboração!
Fica a vontade para visitar e comentar!
Abraço!