Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Procedimento armazenado Oracle, retornando cursor ref vs arrays associativos


A solicitação do DBA não faz sentido.

O que o DBA está quase certamente pensando é que ele quer minimizar o número de mudanças de contexto do mecanismo SQL para PL/SQL que ocorrem quando você está buscando dados de um cursor. Mas a solução que está sendo sugerida é mal direcionada a esse problema específico e apresenta outros problemas de desempenho muito mais sérios na maioria dos sistemas.

No Oracle, uma mudança de contexto de SQL para PL/SQL ocorre quando a VM PL/SQL solicita mais dados à VM SQL, a VM SQL responde executando a instrução ainda mais para obter os dados que ela empacota e devolve ao PL /SQLVM. Se o mecanismo PL/SQL estiver solicitando linhas uma de cada vez e você estiver buscando muitas linhas, é possível que essas mudanças de contexto possam ser uma fração significativa do seu tempo de execução geral. Para combater esse problema, a Oracle introduziu o conceito de operações em massa pelo menos nos 8i dias. Isso permitiu que a VM PL/SQL solicitasse várias linhas por vez da VM SQL. Se a VM PL/SQL solicitar 100 linhas por vez, você eliminou 99% das mudanças de contexto e seu código potencialmente é executado muito mais rápido.

Depois que as operações em massa foram introduzidas, havia muito código que poderia ser refatorado para ser mais eficiente usando explicitamente BULK COLLECT operações ao invés de buscar linha por linha e então usar FORALL loops para processar os dados nessas coleções. Aos 10,2 dias, no entanto, a Oracle havia integrado operações em massa em FOR implícito loops para que um FOR implícito loop agora coleta automaticamente em massa em lotes de 100 em vez de buscar linha por linha.

No seu caso, no entanto, como você está retornando os dados para um aplicativo cliente, o uso de operações em massa é muito menos significativo. Qualquer API decente do lado do cliente terá uma funcionalidade que permite ao cliente especificar quantas linhas precisam ser buscadas do cursor em cada viagem de ida e volta da rede e essas solicitações de busca irão diretamente para a VM SQL, não através do PL /SQL VM, portanto, não há mudanças de contexto SQL para PL/SQL para se preocupar. Seu aplicativo precisa se preocupar em buscar um número apropriado de linhas em cada viagem de ida e volta - o suficiente para que o aplicativo não se torne muito tagarela e gargalo na rede, mas não tantos que você tenha que esperar muito tempo para que os resultados sejam retornado ou para armazenar muitos dados na memória.

Retornar coleções PL/SQL em vez de um REF CURSOR para um aplicativo cliente não reduzirá o número de mudanças de contexto que ocorrem. Mas vai ter um monte de outras desvantagens, entre as quais o uso de memória. Uma coleção PL/SQL deve ser armazenada inteiramente na área global do processo (PGA) (assumindo conexões de servidor dedicado) no servidor de banco de dados. Este é um pedaço de memória que deve ser alocado da RAM do servidor. Isso significa que o servidor terá que alocar memória para buscar cada última linha que cada cliente solicitar. Isso, por sua vez, limitará drasticamente a escalabilidade do seu aplicativo e, dependendo da configuração do banco de dados, poderá roubar a RAM de outras partes do banco de dados Oracle que seriam muito úteis para melhorar o desempenho do aplicativo. E se você ficar sem espaço PGA, suas sessões começarão a receber erros relacionados à memória. Mesmo em aplicativos puramente baseados em PL/SQL, você nunca desejaria buscar todos os dados em coleções, você sempre desejaria buscá-los em lotes menores, a fim de minimizar a quantidade de PGA que você está usando.

Além disso, buscar todos os dados na memória fará com que o aplicativo pareça muito mais lento. Quase qualquer estrutura permitirá que você busque dados conforme necessário, por exemplo, se você tiver um relatório que está exibindo em páginas de 25 linhas cada, seu aplicativo precisaria buscar apenas as primeiras 25 linhas antes de pintar o primeira tela. E nunca teria que buscar as próximas 25 linhas, a menos que o usuário solicitasse a próxima página de resultados. Se você estiver buscando os dados em arrays como seu DBA propõe, no entanto, você terá que buscar todas as linhas antes que seu aplicativo possa começar a exibir a primeira linha, mesmo que o usuário nunca queira ver mais do que o primeiro punhado de linhas. linhas. Isso significará muito mais E/S no servidor de banco de dados para buscar todas as linhas, mais PGA no servidor, mais RAM no servidor de aplicativos para armazenar o resultado em buffer e mais esperas pela rede.