[firebase-br] Campo calculado - vantagens x desvantagens

Gladiston Santana gladiston em vidy.com.br
Sex Fev 6 13:07:08 -03 2015


Uso campos calculados para iteração apenas do registro corrente e isso me
atende bem.
Também uso campos calculados para comentar campos que usam mnemônicos ou
combinações de resultados, por exemplo:
CREATE TABLE (...)
    COM_SITUACAO          COMPUTED BY (
  CASE
    WHEN (status='A') AND
 (COALESCE(dt_primeiro_envio,'1980-01-01')<'1990-01-01') AND (CURRENT_DATE
> DT_PREV_ENVIO) THEN 'Aberta e envio expirado('||trim(prioridade_com)||')'
    WHEN (status='A') AND
 (COALESCE(dt_primeiro_envio,'1980-01-01')<'1990-01-01') THEN 'Aberto e não
enviado('||trim(prioridade_com)||')'
    WHEN (status='A') AND
 (COALESCE(dt_primeiro_envio,'1980-01-01')>'1990-01-01') THEN 'Aberto e
enviado('||trim(prioridade_com)||')'
    WHEN (status='C') AND
 (COALESCE(dt_primeiro_envio,'1980-01-01')<'1990-01-01') AND
(DT_PREV_ENVIO<'1990-01-01') THEN 'Cancelado, porém não enviado'
    WHEN (status='C') AND
 (COALESCE(dt_primeiro_envio,'1980-01-01')>'1990-01-01') THEN 'Cancelada,
mas enviada'
    WHEN (status='D') THEN 'Desistimos'
    WHEN (status='S') THEN 'Suspenso por tempo de inatividade'
    WHEN (status='R') AND
 (COALESCE(dt_primeiro_envio,'1980-01-01')<'1990-01-01') THEN 'Revisada,
porém não enviada'
    WHEN (status='R') AND
 (COALESCE(dt_primeiro_envio,'1980-01-01')>'1990-01-01') THEN 'Revisada,
mas enviada'
    WHEN (status='P') THEN 'Perdido para o concorrente'
    WHEN (status='F') THEN 'Vencemos'
  END),

Como campos calculados são virtuais e essas operações não usam agregadores
então o efeito sobre a performance é pífio.
O beneficio e a simplicidade de campos calculados é indiscutível, mas no
seu caso já usa agregadores então é bom calcular bem o risco, pois se for
algo repetitivo penso eu talvez seja melhor usar em forma de query porque
você poderá prepará-la antes.

Mas faça o teste de mesa e veja os resultados, usando campos calculados,
mesmo que se arrependa depois é fácil reverter, basta não citar esses
campos em sua query e explicitar o group by/subquery/whatever.

Em 6 de fevereiro de 2015 11:43, Hélio Oliveira <hpensador em gmail.com>
escreveu:

> Bom dia Colegas!
>
> Estou trabalhando no desenvolvimento de um sistema e penso em usar
> bastante o recurso de campos calculados em varias colunas de uma tabela.
> Hoje para teste escrevi a instrução SQL de um dos campos calculados, vide
> abaixo:
>
> SELECT SUM(X.VALOR) - (SELECT SUM(X.VALOR)
>                        FROM FOLHA X
>                          JOIN FOLHA_BASE FB ON (FB.COD_EMPRESA =
> X.COD_EMPRESA
>                                             AND FB.MES = X.MES
>                                             AND FB.ANO = X.ANO
>                                             AND FB.SEQUENCIA = X.SEQUENCIA
>                                             AND FB.MATRICULA = X.MATRICULA)
>                          JOIN EVENTO E ON (E.COD_EVENTO = X.COD_EVENTO
>                                        AND E.COD_EMPRESA = X.COD_EMPRESA
>                                        AND E.ESTORNA_BASE_INSS = 'S')
>                          JOIN PARAMETRO P ON (P.COD_EMPRESA = X.COD_EMPRESA
>                                           AND P.FOLHA_MES = X.MES
>                                           AND P.FOLHA_ANO = X.ANO
>                                           AND P.FOLHA_SEQUENCIA =
> X.SEQUENCIA)
>                        WHERE X.COD_EMPRESA = (SELECT
> RDB$GET_CONTEXT('USER_SESSION', 'id_empresa')
>                                               FROM RDB$DATABASE))
> FROM FOLHA X
>   JOIN FOLHA_BASE FB ON (FB.COD_EMPRESA = X.COD_EMPRESA
>                      AND FB.MES = X.MES
>                      AND FB.ANO = X.ANO
>                      AND FB.SEQUENCIA = X.SEQUENCIA
>                      AND FB.MATRICULA = X.MATRICULA)
>   JOIN EVENTO E ON (E.COD_EVENTO = X.COD_EVENTO
>                 AND E.COD_EMPRESA = X.COD_EMPRESA
>                 AND E.INSS = 'S')
>   JOIN PARAMETRO P ON (P.COD_EMPRESA = X.COD_EMPRESA
>                    AND P.FOLHA_MES = X.MES
>                    AND P.FOLHA_ANO = X.ANO
>                    AND P.FOLHA_SEQUENCIA = X.SEQUENCIA)
> WHERE X.COD_EMPRESA = (SELECT RDB$GET_CONTEXT('USER_SESSION',
> 'id_empresa')
>                        FROM RDB$DATABASE);
>
> *Executando o mesmo no IBExpert obtenho o seguinte PLAN (Observação a base
> de dados ainda está vazia).*
>
> Plan
> PLAN (RDB$DATABASE NATURAL)
> PLAN (RDB$DATABASE NATURAL)
> PLAN JOIN (FB NATURAL, X INDEX (PK_FOLHA), E INDEX (PK_EVENTO), P INDEX
> (PK_PARAMETRO))
> PLAN JOIN (FB NATURAL, X INDEX (PK_FOLHA), E INDEX (PK_EVENTO), P INDEX
> (PK_PARAMETRO))
>
> ------ Performance info ------
> Prepare time = 16ms
> Execute time = 0ms
> Avg fetch time = 0,00 ms
> Current memory = 10.393.568
> Max memory = 12.038.880
> Memory buffers = 2.048
> Reads from disk to cache = 0
> Writes from cache to disk = 0
> Fetches from cache = 38
>
> Gostaria da opinião dos nobres, com as vossas experiências posso ter
> problema de lentidão em função desses vários campos calculados?
>
> Será uma vantagem ou desvantagem?



Mais detalhes sobre a lista de discussão lista