[firebase-br] Otimização de Transação

Sandro Souza escovadordebits em gmail.com
Seg Nov 30 10:44:51 -03 2009


Bom dia/tarde Josauro.

Em um sistema que fiz em PHP, eu utilizo essa idéia de reaproveitar códigos
excluídos ou não utilizados como você citou. No meu caso, eu chamei de
"código otimizado" (tapa buraco).

Fiz algumas classes em PHP para facilitar o meu dia-a-dia, e uma delas é o
meu "motor de cadastro", que faz 99% do trabalho que eu teria que fazer
manualmente em cada um dos cadastros do sistema. Eu apenas crio uma
instância dessa classe, e preencho algumas informações básicas, como nome da
tabela, a lista de campos com as suas respectivas informações (nome, tipo,
título para exibição ao usuário, tamanho, etc...) e entre outros detalhes,
como será calculado o próximo valor do último campo que faz parte da chave
primária (campo chave). Quando informo que desejo usar "códigos otimizados",
então faço da seguinte forma:

Primeiramente, verifico se todos os códigos foram utilizados.

Como adotei que o primeiro valor é sempre 1, apenas executo um "SELECT
COUNT(*) QUANT, MAX(ULTIMO_CAMPO_CHAVE) FROM MINHA_TABELA WHERE .......".

Se a quantidade for igual ao maior valor utilizado, então não há "brecha", e
nesse caso, utilizo o maior valor que já foi retornado nesse mesmo select
acrescentando 1, como novo valor e encerro aqui o cálculo do próximo valor.

Caso a quantidade seja menor que o maior valor utilizado, então vou ter que
encontrar o primeiro valor que posso utilizar, usando pesquisa binária para
gastar o mínimo possível de tempo nessa busca.

Vamos a um exemplo fictício. Vamos assumir que o maior valor encontrado
tenha sido 100, e existe uma "brecha" no número 10.

O intervalo inicial da pesquisa binária ficaria de 1 até 100. Calculando a
média entre o início e o fim do intervalo, temos o valor central do
intervalo, que seria 50. E sendo assim, executo o seguinte código:

SELECT COUNT(*) FROM MINHA_TABELA WHERE .......... AND (ULTIMO_CAMPO_CHAVE
<= 50)

O valor retornado, com certeza será menor que 50, pois o número 10 não
consta, então, saberei que a brecha está na primeira metade do intervalo
atual, ou seja, entre 1 e 50. Como já verifiquei o valor 50, então fica de 1
até 49. Recalculando o valor médio do novo intervalo, temos o valor 25. E
agora a nova pesquisa:

SELECT COUNT(*) FROM MINHA_TABELA WHERE .......... AND (ULTIMO_CAMPO_CHAVE
<= 25)

O valor retornado, com certeza será menor que 25, pois o número 10 não
consta, e novamente saberei que a brecha está na primeira metade do
intervalo atual, que agora passará a ser de 1 até 24, com valor central de
12 (divisão inteira).

SELECT COUNT(*) FROM MINHA_TABELA WHERE .......... AND (ULTIMO_CAMPO_CHAVE
<= 12)

Retornou um valor menor que 12, então ainda devo pesquisar na primeira
metade do intervalo atual, que passou a ser de 1 até 11, com centro em 6:

SELECT COUNT(*) FROM MINHA_TABELA WHERE .......... AND (ULTIMO_CAMPO_CHAVE
<= 6)

Agora retornou o valor igual ao valor central, e agora sabemos que os
valores estão totalmente utilizados até o 6, ou seja, a brecha está na
segunda metade do intervalo atual, que passou a ser de 7 até 11, com centro
em 9:

SELECT COUNT(*) FROM MINHA_TABELA WHERE .......... AND (ULTIMO_CAMPO_CHAVE
<= 9)

Novamente retornou o valor igual ao valor central, e agora sabemos que os
valores estão totalmente utilizados até o 9, ou seja, a brecha está na
segunda metade do intervalo atual, que passou a ser de 10 até 11, com centro
em 10:

SELECT COUNT(*) FROM MINHA_TABELA WHERE .......... AND (ULTIMO_CAMPO_CHAVE
<= 10)

Retornou um valor menor que 10, então a brecha está na primeira metade do
intervalo atual, que passou a ser de 10 até 9, ou seja, a pesquisa binária
encerrou aqui porque os limites do intervalo se ultrapassaram. E dessa
forma, encontramos a brecha em 10.

Usando essa técnica de pesquisa binária, você terá a melhor performance,
principalmente se você comparar com a pesquisa sequencial.

Em uma pesquisa sequencial, teriamos feito 10 SELECTs para encontrar a
brecha no valor 10, além do primeiro SELECT para saber se todos os códigos
já estão em ordem, sem brecha. Usando essa técnica de pesquisa binária, além
do primeiro SELECT, fizemos apenas 6 SELECTs em um universo de 100 códigos
para achar a brecha.

Espero ter ajudado mais que atrapalhado. :D

2009/11/30 Josauro S.J. <josauro em casasoft.inf.br>

>
> Em nosssos sistemas adotamos o uso de um arquivo mestre para prover o
> sequencial para as chaves primarias de todas as tabelas, assim faremos o
> reaproveitamento de codigos excluidos ou não usados.
> O problema é que para consistencia, precisa-se abrir uma transação
> especifica para pegar e atualizar o sequencia para na tabela mestre para
> cada registro que se for incluir nas tabelas do sistema, e esse processo se
> torna estremamente lento em inclusões em massa, onde se gere um grande
> número de inclusões em outas tabelas.Com o uso do Generation o processo é
> extremamente rapido.
> Alguem utiliza esse processo, e achou uma solução para tornar esse processo
> mais rapido ?
>
> Obrigado.
> Josauro S.J.
>
>
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>



Mais detalhes sobre a lista de discussão lista