Blog

  • Novos Recursos – PL/SQL 10g

    Olá Pessoal. O Oracle 10g apresentou novos recursos para linguagem de programação PL/SQL. Nesse artigo serão apresentados esses novos recursos, com devidas críticas.

    Melhorias:

    Desempenho:

    • Está duas vezes mais rápido que a versão 9i (que era três vezes mais rápido que a versão 8i).
    • O interpretador foi reescrito.
    • Identificação de expressões semelhantes.
    • Parâmetro PLSQL_OPTIMIZE_LEVEL (zero a dois).
    • Quanto maior, mais tempo de compilação e mais rápida execução.

    Tipos de Dados:

    • BINARY_FLOAT e BINARY_DOUBLE: para ponto flutuante.
    Menos espaço e mais rápido que NUMBER.
    • PLS_INTEGER continua sendo a melhor opção.
    Novo intervalo: -2147483648 e 214748364.
    LOB elimina o limite de 4GB: depende do SO e da instalação.

    Caracteres Literais:

    Pode-se utilizar qualquer caractere (q’).

    Exemplo:

    begin
    
    dbms_output.put_line( q'[Imaster's]' );
    
    dbms_output.put_line( q'%Imaster's%' );
    
    end;
    
    / 

    Comando FORALL:

    • Aumenta velocidade por mandar todos comandos DML de uma só vez.
    • Novas cláusulas para prever “buracos” na seqüência:

    INDICES OF: valores dos índices das coleções

    VALUES OF: atua em uma coleção indexada

    1-

    declare
    
    TYPE a_Master IS TABLE OF varchar2(20) INDEX BY PLS_INTEGER;
    
    v_Master a_Master;
    
    begin
    
    FOR x IN 1..10 LOOP
    
      v_Master(x) := 'Item ' || x;
    
    END LOOP;
    
    v_Master.DELETE(3,5);
    
    FORALL x IN v_Master.FIRST..v_Master.LAST
    
      INSERT INTO Tabela
    
       VALUES (v_Master(x));
    
    end;
    
    / 

    2-

    create table tabela ( modelo varchar2(100) );
    
    declare
    
    TYPE a_Master IS TABLE OF varchar2(20) INDEX BY PLS_INTEGER;
    
    v_Master a_Master;
    
    begin
    
    FOR x IN 1..10 LOOP
    
      v_Master(x) := 'Item ' || x;
    
    END LOOP;
    
    v_Master.DELETE(3,5);
    
    FORALL x IN INDICES OF v_Master
    
      INSERT INTO tabela
    
       VALUES (v_Master(x));
    
    end;
    
    /
    
    SELECT * FROM tabela;

    3-

    delete from tabela;
    
    declare
    
    TYPE aRel IS TABLE OF pls_integer;
    
    TYPE a_Master IS TABLE OF varchar2(20) INDEX BY PLS_INTEGER;
    
    v_Master a_Master;
    
    vRel aRel:=aRel(1,2);
    
    begin
    
    FOR x IN 1..10 LOOP
    
      v_Master(x) := 'Item ' || x;
    
    END LOOP;
    
    v_Master.DELETE(3,5);
    
    FORALL x IN VALUES OF vRel
    
      INSERT INTO tabela
    
       VALUES (v_Master(x));
    
    end;
    
    /
    
    SELECT * FROM tabela; 

    WARNINGs:

    • Até versões anteriores: somente erros de sintaxe e dependência entre objetos.
    • Agora possui níveis de alerta.

    ALL: indicará todos os alertas possíveis.

    PERFORMANCE: somente alertas relacionados ao desempenho serão mostrados.

    INFORMATIONAL: somente alertas relacionados à facilidade de manutenção do código

    serão mostrados.

    SEVERE: quando há problemas de lógica no código.

    Específico:

    O desenvolvedor especifica qual erro quer monitorar.

    Exemplo:

    show parameter plsql_warnings
    
    alter system set plsql_warnings='ENABLE:PERFORMANCE', 'ENABLE:SEVERE';
    
    DROP TABLE tabela;
    
    CREATE TABLE tabela (  codigo NUMBER, modelo VARCHAR2(60) );
    
    CREATE OR REPLACE PROCEDURE teste (n_codigo VARCHAR2, c_modelo VARCHAR2)
    
    IS
    
    BEGIN
    
      INSERT INTO TEMP (codigo, modelo)
    
       VALUES (n_codigo, c_modelo);
    
    END;
    
    / 
    
    Wrap x DBMS_DDL: 

    Esconde o código fonte do PL/SQL.

    Exemplo:

    DECLARE
    
       ddl VARCHAR2(32767);
    
    BEGIN
    
       ddl :=       'CREATE OR REPLACE PROCEDURE teste (n_codigo VARCHAR2,
    
                                                        c_modelo VARCHAR2) ';
    
       ddl := ddl || 'IS ';
    
       ddl := ddl || 'BEGIN ';
    
       ddl := ddl || '  INSERT INTO tabela (codigo, modelo)';
    
       ddl := ddl || '       VALUES (n_codigo, c_modelo); ';
    
       ddl := ddl || 'END;';
    
       EXECUTE IMMEDIATE SYS.DBMS_DDL.WRAP(ddl);
    
    END;
    
    / 
    
    SELECT * FROM USER_SOURCE
    
    WHERE NAME = 'TESTE'; 

    Expressões Regulares:

    01. Busca padrões em conteúdos.

    02. Exemplos de Utilização:

    • Restrição de conteúdo (CONSTRAINTS)
    • Buscas complexas e mineração de dados.

    03. Tipos:

    • REGEXP_REPLACE: busca e substitui um padrão. Utilidade: localizar um padrão e efetuar modificações na forma de visualização. Ex.: formatação de telefone.

    Exemplo:

    declare
    
    celular_A varchar2(25):='xx1112341234';
    
    celular_B varchar2(15):='11.1234.1234';
    
    celular_C varchar2(15):='1234.1234';
    
    begin
    
    dbms_output.put_line( 'Muda    =>' || regexp_replace( celular_A,
    
                            '([=xx=]{2})([[:digit:]]{2})([[:digit:]]{4})
    
                             ([[:digit:]]{4})',
    
                            '(\1) \2-\3-\4') );
    
    dbms_output.put_line( 'Modifica     =>' || regexp_replace( celular_A,
    
                            '([[:alpha:]]{2})([[:digit:]]{2})([[:digit:]]{4})
    
                             ([[:digit:]]{4})',
    
                            '(\1) \2-\3-\4') );
    
    dbms_output.put_line( 'Modifica     =>' || regexp_replace( celular_B,
    
                            '([[:digit:]]{2})\.([[:digit:]]{4})\.([[:digit:]]{4})',
    
                            '\1-\2-\3' ) );
    
    dbms_output.put_line( 'Não faz nada =>' || regexp_replace( celular_B,
    
                            '([[:digit:]]{2})\-([[:digit:]]{4})\-([[:digit:]]{4})',
    
                            '\1-\2-\3' ) );
    
    dbms_output.put_line( 'Modifica     =>' || regexp_replace( celular_C,
    
                            '([[:digit:]]{4})\.([[:digit:]]{4})',
    
                            '\1-\2' ) );
    
    end;
    
    / 
    • REGEXP_LIKE: retorna se há ou não aderência a um padrão. Utilidade: refinar o resultado de uma pesquisa.

    Exemplo:

    declare
    
    type a_Master is varray(7) of varchar2(10);
    
    v_Master a_Master:=a_Master('estudar', 'estudando', 'estudado', 'estudante' );
    
    begin
    
    for x in 1..4 loop
    
      if regexp_like( v_Master(x), 'estud((ar)+|(ando)|(ado))' ) then
    
        dbms_output.put_line( v_Master(x) );
    
      end if;
    
    end loop;
    
    end;
    
    / 
    • REGEXP_SUBSTR: indica qual parte da cadeia de caracteres adere ao padrão.

    Exemplo:

    begin
    
    dbms_output.put_line( regexp_substr( 'O universitario deve ter estudado para realizar a prova','estud((ar)+|(ando)|(ado))' ) );
    
    end;
    
    / 
    • REGEXP_INSTR: retorna se o padrão existe na cadeia de caracteres. Utilidade: pesquisas que envolvem padrões, como seqüências de DNA ou de dados astronômicos.

    Exemplo:

    begin
    
    dbms_output.put_line( regexp_instr(
    
          'O universitario deve ter estudado e precisa estudar muito para realizar a prova',
    
          'estud((ar)+|(ando)|(ado))') );
    
    end;
    
    / 

    Compilação Condicional:

    1. Permite selecionar parte do código para compilação.

    2. Exemplos de utilização.

    • Diferentes releases de software.
    • Funcionalidades adicionais em função da versão do BD.
    • Testes de novas versões de software.
    • Personalização e customização para clientes.

    3. Disponibilidade

    • Oracle 9i (9.2.0.6)
    • Oracle 10g (10.1.0.4)

    4. Parâmetro:

    • PLSQL_CCFLAGS

    5. Pacotes:

    • DBMS_DB_VERSION
    • DBMS_PREPROCESSOR

    1

    alter session set PLSQL_CCFlags = 'Teste1:true, Teste2:false'; 
    
    CREATE OR REPLACE PROCEDURE TESTE IS
    
    cVAR1 BOOLEAN := $$Teste1;
    
    BEGIN
    
    IF $$Teste2 THEN
    
       DBMS_OUTPUT.PUT_LINE( 'Variável $$Teste2 é VERDADEIRA' );
    
    ELSE
    
       DBMS_OUTPUT.PUT_LINE( 'Variável $$Teste2 é FALSA' );
    
    END IF;
    
    END;
    
    / 
    
    EXEC TESTE 
    
    alter session set PLSQL_CCFlags = 'Teste1:0, Teste2:false'; 
    
    CREATE OR REPLACE PROCEDURE TESTE IS
    
    BEGIN
    
    $IF $$Teste2 $THEN
    
       DBMS_OUTPUT.PUT_LINE( 'Variável $$Teste2 é VERDADEIRA' );
    
    $ELSE
    
       DBMS_OUTPUT.PUT_LINE( 'Variável $$Teste2 é FALSA' );
    
    $END
    
    IF $$Teste1 IS NOT NULL THEN
    
       DBMS_OUTPUT.PUT_LINE( 'Variável $$Teste1 é' || $$Teste1 );
    
    END IF;
    
    END;
    
    / 
    
    EXEC TESTE 

    2

    BEGIN
    
    $IF DBMS_DB_VERSION.VER_LE_10_1 $THEN
    
      $ERROR 'Versão do banco de dados não suporta esta função' $END
    
    $ELSE
    
      DBMS_OUTPUT.PUT_LINE ('Versão ' || DBMS_DB_VERSION.VERSION || '.' ||
    
      DBMS_DB_VERSION.RELEASE || ' suporta esta função.');
    
      COMMIT WRITE IMMEDIATE NOWAIT;
    
    $END
    
    END;
    
    /

    3

    CALL DBMS_PREPROCESSOR.PRINT_POST_PROCESSED_SOURCE('PROCEDURE', 'SGI', 'TESTE'); 
    
    Data Mining: 
    
    Oracle 10g R 2 , Pacote: DBMS_PREDICTIVE_ANALYTICS 
    
    Procedimento EXPLAIN: analisa o conjunto de dados para explicar o valor de cada atributo. Quanto maior o valor, mais  forte o relacionamento entre os dados. 
    
    Código para gerar a explicação:
    
    begin
    
    DBMS_PREDICTIVE_ANALYTICS.EXPLAIN(
    
       DATA_TABLE_NAME => 'PARCELA',
    
       EXPLAIN_COLUMN_NAME => 'STPARCELA',
    
       RESULT_TABLE_NAME => 'AA_EXPLAIN_RESULTS' );
    
    end;
    
    /
    
    SELECT * FROM AA_EXPLAIN_RESULTS; 

    Procedimento PREDICT: retorna um conjunto de valores que permite analisar o grau de confiança na previsão do conjunto de dados.

    Código para gerar a previsão:

    SET SERVEROUTPUT ON
    
    DECLARE
    
       v_predict_accuracy NUMBER(30,10);
    
    BEGIN
    
       DBMS_PREDICTIVE_ANALYTICS.PREDICT (
    
           ACCURACY            => v_predict_accuracy,
    
           DATA_TABLE_NAME     => 'PARCELA',
    
           CASE_ID_COLUMN_NAME => 'CDCONTR',
    
           TARGET_COLUMN_NAME  => 'STPARCELA',
    
           RESULT_TABLE_NAME   => 'AA_PREDICT_RESULTS');
    
       DBMS_OUTPUT.PUT_LINE('*** Accuracy ***');
    
       DBMS_OUTPUT.PUT_LINE(v_predict_accuracy);
    
    END;
    
    /
    
    *** Accuracy ***
    
          ,5727376841 

    Para maiores detalhes, você pode ler PL/SQL User’s Guide and Reference (disponível para download no endereço http://www.oracle.com/pls/db102/homepage).

    Por hoje é tudo pessoal. Até o próximo artigo!

    “Keeping IT Running”

  • Bancos são birôs modernos

    Os birôs de serviços, populares nos anos 70, ofereciam processamento de dados para empresas. Era um tipo de terceirização de serviços que as empresas eram “obrigadas” a fazer devido a completa falta de profissionais de informática e custos proibitivos para aquisição de hardware e software. Óbvio, custava mais barato pagar pelo processamento, por exemplo, da folha de pagamento e contabilidade do que fazê-la manualmente na própria organização.

    Do final dos anos 70 até hoje, com o advento do microcomputador e outra montanha de inovações e possibilidades tecnológicas, os birôs, como conhecidos anteriormente, foram desaparecendo. Porém, ainda existem alguns que podem se ofender ao chamá-los de birôs como o Serpro, a Dataprev e os bancos. Bancos?

    Sim! Bancos. Aquele lugar onde, aproximadamente, 70 milhões de brasileiros têm conta corrente ou poupança. É o lugar onde se contratam seguros, previdência, cartão de crédito e uma lista de mais de 100 produtos (serviços). Pelo serviço de manutenção de conta-corrente o cliente pode pagar, em média, R$ 20,00. Pois bem, este serviço e seus subjacentes, emissão de saldo e extrato, depósitos e saques, são quase que exclusivamente prestados por serviços de informática. Com exceção de algumas pequenas partes dos processos de abertura da conta corrente e do depósito e saque que lidam com numerário o restante é eletrônico.

    Aos mais céticos que não querem concordar com essa semelhança, pode-se oferecer uma sutil diferença. Os birôs dos anos 70 serviam apenas a grandes e médias empresas e governo enquanto que os birôs/bancos atuais, prestam serviços de processamento de dados para qualquer um disposto a pagar uma “tarifazinha” e que o banco queira como cliente.

    Alguns outros serviços podem ter quantidades ainda maiores de processamento de dados. Por exemplo, o serviço de cobrança para pessoas jurídicas pode ser algo puramente eletrônico, ou seja, o banco atua totalmente como birô recebendo, processando e devolvendo informações sem qualquer intervenção de atendimento a clientes.

    Contudo, outros serviços, como custódia de valores pode ter boa parte do trabalho manual e usar mais características de banco do que de birô de serviços eletrônicos.

    Enfim, a visão “romântica” dos bancos como empresas aonde clientes entravam e saiam com dinheiro (numerário) e bancários anotavam, recebiam e pagavam está morrendo. Agora são “birôs de serviços” que fazem isso com seus digitadores, conferentes e vendedores de soluções informatizadas, programadores de remessas de arquivos, analistas de sistemas, consultores de como se servir melhor da Internet, só está faltando trocar o nome para Birô do Brasil, Birô Brasileiro de Descontos, Birô Itaú.

  • Gerência do Açoite

    Quando pensamos no antigo Egito, surgem as imagens das pirâmides, com todos aqueles escravos trabalhando nas pedreiras e seus “supervisores”, com açoites nas mãos, vigiando qualquer trabalhador que estivesse diminuindo o ritmo ou evitando trabalho. Ao menor sinal de esmorecimento, o supervisor fazia ameaças ou usava o açoite para fazer com que o escravo trabalhasse a todo vapor. Essa pressão constante era necessária para fazer com que aquelas pessoas fizessem o trabalho mesmo não recebendo nada para fazê-lo.

    Essa cultura de exercer pressão para fazer com que as pessoas trabalhassem com toda a sua energia aconteceu também em outros lugares do mundo, desde os escravos negros do Brasil até os primeiros funcionários das primeiras indústrias inglesas. Funcionários eram coagidos a trabalhar por horas a fio, recebendo dinheiro que não era suficiente nem para garantir as suas necessidades primárias, sendo lembrados o tempo todo por seus supervisores que se eles não dessem o máximo de si, seriam mandados embora.

    Os “supervisores” responsáveis por exercer pressão acreditavam que isso fazia com que os seus funcionários trabalhassem mais e conseqüentemente produzissem mais. Essa crença enraizou-se no nascimento da indústria e terminou se entranhando de vez na cultura das corporações mundo a fora. Fazer pressão em cima de seus funcionários é uma das maneiras mais eficazes de fazê-los produzir mais sem ter que pagar nenhum centavo a mais por isso. Ou pelo menos é nisso que os gerentes que fazem isso desejam acreditar.

    Atingindo os limites

    O escravo que trabalhava na construção da pirâmide tinha uma vida infernal, comia mal, dormia mal, passava o dia inteiro exposto a um sol inclemente e fazendo esforço físico o tempo todo com pouca água. Rapidamente ele poderia desidratar e ficar fadigado. Era nesse momento que chegava o supervisor, que com o seu açoite “convencia” o escravo a continuar trabalhando.

    Com medo de continuar sendo maltratado e receando os danos físicos a curto prazo causados pelo açoite, o escravo buscava nas suas últimas forças a coragem pra manter o ritmo de trabalho. Sugava tudo que era possível, mesmo que ao final do dia estivesse tão exausto e dolorido que até para dormir teria dificuldade. No dia seguinte, ainda cansado pela noite terrível, ele seria exposto mais uma vez ao trabalho insalubre.

    Daqui pra frente a história começaria a repetir-se, ele iria diminuir o ritmo mais uma vez, sendo castigado por isso, até que ele não tivesse mais nenhuma condição de trabalhar, podendo até mesmo morrer, já que se não trabalhava mais, não teria mais como “pagar” a sua alimentação. Esse cenário não era pontual, acontecia normalmente nas construções das pirâmides e, a cada vez que isso acontecia, a construção perdia um trabalhador e com a perda desse trabalhador a obra perdia também velocidade. No fim, isso não era problema, bastava arranjar outro escravo, mostrar-lhe como era o trabalho e rapidamente ele estaria lá repetindo o serviço.

    Às vistas dos supervisores, a perda desse “funcionário” era válida, ela mantinha todos os outros trabalhando com afinco por medo de sofrerem do mesmo destino. Como eles não quantificavam o “ganho” que era criado pela aplicação de pressão, também não poderiam quantificar a “perda” que a saída de um dos escravos causava na construção do monumento. Ora, se nada era quantificado, nada estava sendo perdido, qualquer coisa que viesse seria lucro.

    Pessoas que exercem trabalhos braçais ou repetitivos que não exigem trabalho intelectual, quando sob pressão, procuram executar os trabalhos mais rápido, remover ou diminuir os momentos de improdutividade ou até mesmo pular fases que elas acreditam que não são essenciais para o serviço. Mas para tudo isso existe um limite e, especialmente para trabalhadores braçais, o limite do corpo é um dos primeiros que se manifesta.

    As pessoas ficam sonolentas, começam a ter problemas de concentração, e começam a produzir menos, mesmo com toda a pressão que está sendo exercida, elas simplesmente não têm mais de onde retirar energia para manter o ritmo frenético que os seus superiores estão exigindo e com isso, a produtividade começa a diminuir até o ponto de que as pessoas vão começar a produzir muito menos do que produziam no seu estado normal.

    “Mas quem faz trabalho intelectual não vai sofrer dessa estafa física nem muito menos vai ser tratado na base do açoite, um pouco de pressão não vai fazer mal nenhum”, é o que você ouviria de um “gerente” que usa esse tipo de prática em equipes que fazem trabalho intelectual. É uma pena que ele provavelmente nunca parou pra medir a “produtividade” das suas “vítimas”.

    Pessoas não podem pensar “mais rápido”

    Essa é a primeira e única lei que você precisa conhecer antes de tentar pressionar as pessoas que fazem trabalho intelectual para produzirem mais. Elas não podem pensar mais rápido e nada do que você possa fazer vai mudar isso, simplesmente faz parte da natureza delas. A velocidade que uma pessoa é capaz de organizar os seus pensamentos é igual para tudo o que ela faz.

    Citando Tim Lister:

    “People under time pressure do not think faster”.

    Quando alguém que faz trabalho intelectual é pressionado a produzir mais e mais rápido em menos tempo, não existem muitas escolhas. Na verdade, ele pode fazer ainda menos do que o nosso escravo no exemplo anterior, pois ele não pode aumentar a velocidade do seu trabalho, ele só pode eliminar tempo improdutivo e remover ou adiar fases do seu trabalho que ele ache que não sejam críticas para o que ele está fazendo.

    Eliminar o tempo, em uma empresa bem organizada, não vai surtir muito efeito, já que praticamente todo o tempo do funcionário já vai estar dedicado a fazer o seu trabalho. E devemos lembrar que quando ele sai nessa busca de remover todos os momentos de tempo livre, ele vai perder a sua capacidade de inovar graças ao ócio, ele vai estar tão preocupado em produzir que não vai se preocupar com mais nada.

    Como eliminar o tempo perdido não foi o suficiente, agora ele vai ter que apontar a arma para outra coisa e agora ele só tem a remoção de trabalho que ele ache que não é importante. Ele vai remover fases que, para ele, só aumentam o tempo sem oferecer um ganho direto, ele pode até mesmo acelerar fases que deveriam durar mais, como a concepção da arquitetura do sistema, pra perder o mínimo de tempo possível.

    Tomemos como exemplo um desenvolvedor. Ele está trabalhando em um projeto que já está atrasado e o seu gerente está pressionando cada vez mais para que eles possam se manter no prazo. Como ele sabe que nada no mundo vai fazer o projeto caminhar mais rápido, começa a selecionar as fases a serem “deixadas pra depois”. A primeira fase a ser vitimada é a fase de testes. Ele começa a escrever código sem escrever testes que garantam que aquele código funciona corretamente. Infelizmente, isso ainda não é o suficiente para fazer com que o projeto volte ao prazo, então vai ser necessário cortar mais alguma das fases.

    O desenvolvedor percebe que perde muito tempo conversando com o cliente sobre as funcionalidades que o sistema deve ter, então ele corta o contato com o cliente e começa a desenvolver simplesmente baseado nos requisitos que tem sem considerar a opinião do cliente no que está sendo feito. Agora sim, o desenvolvedor finalmente conseguiu fazer com que o projeto estivesse entregue no prazo.

    Na data que havia sido planejada e endurecida pelo gerente do projeto nos seus momentos de terrorismo emocional (e profissional), o projeto foi entregue. Ou pelo menos tentaram entregar alguma coisa. Como os testes e o contato com o cliente foram removidos para fazer com que o projeto caminhasse mais rápido, ao entrar em produção o sistema nem representava realmente o que o cliente desejava e ainda estava cheio de problemas e bugs que deveriam ser consertados o mais rápido possível. E lá vamos nós para o ciclo de pressão mais uma vez.

    E o que vem depois

    A pessoa ou equipe que vive sobre essa pressão constante vai começar a apresentar os mesmos sinais de estafa que os nossos trabalhadores braçais do exemplo anterior. Eles começam a sentir-se usados pela empresa, que busca sugar deles até a última gota de energia, percebem que, para ela, eles não passam de meros recursos que vão ser utilizados até que não haja mais nada que possa ser aproveitado.

    Com esse sentimento vem a insatisfação, com a insatisfação vem a diminuição da produtividade, mesmo sobre pressão e, depois disso, essas pessoas já estão distribuindo os seus currículos na concorrência em busca de um lugar mais humano para trabalhar.

    No caso dos nossos trabalhadores braçais ou de serviços repetitivos, o custo de colocar uma nova pessoa no serviço é baixo, já que o funcionário que saiu simplesmente repetia um processo que havia sido definido dentro da própria empresa, ele não mantinha nenhum conhecimento específico sobre como fazer o seu trabalho, tudo o que ele fazia poderia ser ensinado rapidamente a um terceiro e ele estaria produzindo rapidamente.

    Já no trabalho intelectual o caso se inverte, o funcionário tem o processo em sua cabeça, é o seu conhecimento pessoal que cria o produto que a empresa vende e a perda desse profissional vai ser custosa para ela. Não é possível simplesmente colocar outra pessoa no lugar daquele que está saindo. O novo funcionário vai ter que ser treinado no serviço, e ele dificilmente vai conseguir a experiência que o que está saindo tinha em pouco tempo. O custo para a empresa na perda de um trabalhador intelectual vai ser terrível, e tudo isso porque o gerente acreditava que um pouco de pressão não faria mal a ninguém.

    O ganho de “produtividade” que existe quando um gerente pressiona os seus gerenciados é ínfimo e no longo prazo ele vai resultar pessoas saindo da empresa, baixa produtividade, incapacidade de responder a mudanças, equipes estressadas e prazos e projetos que nunca são cumpridos. Fazer terrorismo emocional e profissional para tentar fazer com que as pessoas dêem o máximo de si não é o caminho, pessoas que fazem o que gostam da maneira que gostam, dão o máximo de si no trabalho.

    Citando o grande Soichiro Honda:

    “Each individual should work for himself. People will not sacrifice themselves for the company. They come to work at the company to enjoy themselves.”

  • Pimp My Database

    Como consultor de banco de dados há um bom tempo, é inevitável não dispor de uma grande quantidade de histórias. Algumas divertidas, outras interessantes e, infelizmente, muitas tristes. Quando digo tristes, me refiro às situações onde me deparei com ambientes dignos de uma pegadinha, daquelas que você se pergunta onde está a câmera escondida. Pois bem, neste artigo vou contar uma história que qualquer profissional que trabalha com consultaria está sujeito.

    Para os leitores que não entenderam o título, eu vou explicar. Após refletir sobre esta história, não pude deixar de compará-la com um programa da MTV chamado “Pimp My Ride”. Este programa, em resumo, escolhe um participante que possui um carro todo esculhambado. E quando digo esculhambado estou sendo generoso, pois a maioria dos veículos escolhidos é praticamente um lixo ambiente. O apresentador do programa vai até o dono do veículo, apresenta-se e diz que vai envenená-lo (pimp), no bom sentido, é claro.

    Após apresentar o veículo para a equipe de produção do programa, isto é, os profissionais que fazem todo o trabalho “sujo”, a equipe começa a literalmente desmontar o veículo sempre evidenciando o estado lastimável do carro. É impressionante o que as pessoas fazem com seus veículos, chegando ao ponto de utilizar até um absorvente (?) para evitar que a chuva caia dentro do carro.

    Depois da desmontagem a equipe do programa começa a fazer ajustes, leia-se quase completa reconstrução. O veículo então é re-apresentado ao seu dono, que fica abismado com o resultado. Pronto, o veículo está envenenado para a surpresa do dono. Um amigo me disse que já copiaram a versão americana do programa, e que a versão nacional deste programa se chama “Lata Velha” e é apresentado pelo Luciano Huck.

    Voltado para a história da consultoria, lembro-me de ter sido chamado para prestar uma consultoria a uma empresa que estava com alguns problemas em seu banco de dados. Esta empresa utilizava uma aplicação para a Web desenvolvida em ASP (o antigo, não o ASP.NET) com um banco de dados SQL Server 2000. Com apenas estes detalhes em mãos me dirigi para o cliente.

    Após a recepção, me encontrei com a equipe técnica responsável pela aplicação. Equipe era o que eu pensava, pois só havia um responsável técnico. Para não citar nomes, vamos chamar este profissional de Sr. José. Zé para os colegas de trabalho. Simpático, Zé me contou um pouco da história do ambiente. Disse-me que a aplicação foi desenvolvida e era de responsabilidade de dois outros profissionais, que receberam uma proposta de trabalho melhor e decidiram sair da empresa. Zé foi chamado às pressas e, em apenas uma semana, teve que aprender praticamente tudo sobre o negócio, a aplicação, o ambiente (servidores, cabeamento, links de internet etc) e do banco de dados. Como descobri depois, a aplicação e o ambiente são uma responsabilidade muito grande para apenas uma pessoa. Ainda mais com apenas uma semana de aprendizado. Pobre Zé, fez tudo ao seu alcance, mais ainda estava com muitas dificuldades para tocar o barco.

    Infelizmente este cenário não me assusta mais. Já prestei tantas consultorias com situações semelhantes a esta que já me acostumei. Nestas situações, primeiro mantenho a calma e resolvo dar um passo por vez. Por acaso leitor, essa situação lhe traz alguma recordação? Caso positivo, isto apenas confirma a minha tristeza em reação às situações que muitos profissionais da área de Tecnologia da Informação estão sujeitos.

    Após uma breve explicação sobre as regras de negócio e como a aplicação funcionava, bem por cima, pois nem Zé sabia direito muitas coisas, conheci os principais problemas que demandaram a minha consultoria. Zé me apresentou uma lista dos problemas que eu precisava ajudar a resolver, que incluíam: problemas com desempenho, defeitos na aplicação e falhas na segurança.

    Vou abrir um pequeno parêntese aqui. Logo no começo do trabalho fiz questão de deixar bem claro que a minha especialidade é banco de dados e que, apesar de conhecer outras áreas, só poderia ajudá-lo no que diz respeito à minha especialidade.

    Antes de começar a descrever tecnicamente o cenário com o qual me deparei, deixo aqui uma dica de profissionalismo: não procure culpar as pessoas, pelo menos não diretamente e não antes de resolver a situação. Em diversas situações é comum atribuir uma grande parte dos problemas aos técnicos envolvidos. Porém, nem sempre eles são culpados ou podem levar a culpa. Muitas vezes quem é o responsável pela parte técnica sofre pressões ou mesmo é orientado a proceder de certa maneira que, mais cedo ou mais tarde, vai gerar um problema sério. Por exemplo, já perdi a conta de quantas vezes tive que me debugar um código fonte escrito por alguém de madrugada, sendo sustentado por doses cavalares de café.

    Por isso, raramente procuro culpados no momento em que me deparo com problemas graves. Ainda mais durante uma consultoria, pois este tipo de atitude pode levar à atritos com a equipe técnica da empresa.

    Voltando para o ambiente e para o Zé, fui dar uma olhada em seu servidor de banco de dados, que estava sendo executado em uma máquina dedicada para o banco de dados da aplicação Web.

    Lembrando-se agora, gostaria que o Zé tivesse me preparado psicologicamente para o que eu iria encontrar. Sabe um daqueles acidentes de trânsito com engavetamento? Pois é, isso descreve parcialmente a confusão que estava neste servidor. Vou descrever aqui os “pequenos” problemas, de acordo com o Zé.

    Verificando a memória utilizada, constatei que o servidor já tinha consumido toda a memória física e já estava utilizando a memória virtual. Quase sem espaço nas duas HDs, o servidor estava tão lento que até para logar demorar um tempão. O mais impressionante, porém, foi descobrir a quantidade de vírus (isso mesmo, vírus no servidor de banco de dados!) e de aplicativos de usuário instalados. Segurança? Praticamente nenhuma, pois além da senha do administrador ser curta, já fazia pelo menos um ano que ela não era trocada.

    Fiquei receoso de perguntar sobre backup. “Bom, de vez em quando eu copio o conteúdo da pasta Meus Documentos para um CD que fica ali na gaveta”, disse-me Zé quando lhe perguntei sobre cópias de segurança.

    Atualizações? “Uma vez eu tentei aplicar o SP2 no servidor mais demorou muito e parei o processo”, afirmou Zé. Neste ponto eu já imaginava como é que a aplicação estava de pé funcionando neste ambiente….

    “O que mais faltava?”, pensei eu. Mais ainda tinha muito mais por vir! Zé me disse que, não raramente, a rede ficava tão lenta que não dava nem para acessar remotamente o servidor. Mas o pior mesmo, segundo ele, era quando o servidor simplesmente desligava sem nenhuma razão aparente, tornando indisponível a aplicação Web. E, por falar na aplicação, ele me disse que o dono da empresa estava pensando em cancelar todo o site, pois devido aos inúmeros problemas, não estava valendo a pena manter os custos operacionais. Isto por que a aplicação chegou a ser responsável por 5% do faturamento da empresa.

    Logo que eu e o Zé terminamos de levantar todos os principais problemas, procurei deixar uma coisa bem clara: da mesma maneira que no programa “Pimp My Ride”, eu sempre presto consultoria não apenas para resolver o problema imediato do cliente, mais também para mostrar, passo a passo, o que foi feito, aproveitando a oportunidade para treinar e capacitar os profissionais envolvidos. Acredito que, desta maneira, não apenas resolvo o problema imediato, que muitas vezes pode ser descrito como “apagar incêndios”, mas também agrego conhecimento à equipe técnica responsável.

    Voltando para o ambiente, o primeiro passo foi planejar como implementar todas as mudanças necessárias com o menor downtime possível, isto é, alterar as configurações do servidor sem deixar o site fora do ar. Utilizamos temporariamente um servidor, com menor poder de processamento, memória e disco, com uma cópia do banco de dados para possibilitar as alterações do servidor. A aplicação também foi modificada, por Zé, alertando aos usuários que alguma instabilidade poderia ocorrer durante o período de manutenção. Feito isso, nos propusemos a modificar o servidor de banco de dados.

    O primeiro passo foi desabilitar uma série de serviços desnecessários. Suporte à multimídia, impressão e serviços de acesso remotos não essenciais foram apenas alguns dos serviços desabilitados. Só com esta ação o servidor já apresentou uma diminuição na memória utilizada. O próximo passo foi retirar todos os vírus, spywares e outras pragas virtuais. Após esta retirada, foi a vez de remover uma série de softwares desnecessários, como leitores de e-mail, plug-ins para o navegador e muitos outros. Para garantir que nenhum outro tipo de software desnecessário fosse instalado, foram configuradas políticas de domínio para bloquear a execução de uma série de aplicações, incluindo os navegadores.

    O próximo passo foi passar todas as atualizações: service packs do windows, service packs do SQL Server e demais patchs e hotfixes. Em seguida, combinei com Zé que deveríamos instituir uma política se usuários e senhas, reforçadas por regras como:

    • Troca de senha a cada três meses;
    • Desabilitar as contas padrão;
    • Forçar senhas com letras, números e caracteres especiais que tenham um tamanho mínimo de 10 posições;
    • Outras políticas gerais de senha, como o cancelamento após um algumas tentativas e horários definidos para certos usuários.

    Um detalhe importante a ser considerado, quando se fala de política de senhas, é a parte humana. Deixei bem claro para Zé que apenas reforçar a segurança com soluções tecnológicas não adiantava muito: é importante reforçar a segurança com políticas que envolvam as pessoas como, por exemplo, políticas que deixam claro que os administradores não devem anotar senhas em um papel. Infelizmente é necessário também definir certas punições para evitar o risco de quebra na segurança e também para coibir os usuários a vazar informações. No final das contas, um documento contendo a política de segurança foi escrito.

    Mais alguns acertos no servidor e partimos para o banco de dados. O primeiro passo foi identificar o que estava sendo utilizado ativamente pela aplicação e o que era histórico. Com a posse desta informação, “quebrei” o banco de dados em dois, com o objetivo de separar as informações mais utilizadas daquelas que foram consideradas histórico.

    Além disso, modifiquei parâmetros específicos no servidor para garantir que o acesso a memória seja mais “econômico” e que o banco de dados não cresça tanto. Alias o problema de espaço em disco esta ligado ao banco de dados: como não havia backup periódico do banco de dados, e este estava com o recovery Model Full e com todas as opções de auto-crescimento habilitadas (o que, infelizmente, é a realidade em muitas empresas que adotam o SQL Server como servidor de banco de dados) o arquivo de Transaction Log cresceu absurdamente. Modifiquei as configurações da base de dados, separei os arquivos de dados e de Transaction log e elaborei uma rotina de backup periódica e automática para resolver estes problemas. Sempre lembrando que, a cada modificação no servidor ou ação tomada, eu explicava para Zé o que estava acontecendo, que se encarregava de documentar o procedimento.

    Com a questão da memória e do disco resolvidas, fui verificar o uso do processador. Apesar de possuir um alto pode de processamento, não raramente a CPU acusava o uso de 100% de processamento. Comecei a identificar os pontos onde isso acontecia e, aplicando técnicas para distribuir a carga, utilizar índices e otimizar stored procedures, consegui evitar o uso excessivo de processamento, por parte do servidor de banco de dados. Memória, CPU e disco já estavam ajustados, só faltava agora a rede.

    Para entender o porquê da lentidão na rede, tive que analisar como a aplicação interagia com o servidor de banco de dados. Para isso, utilizar o Profiler e captei as principais consultas enviadas para o servidor de banco de dados. E não eram poucas. Resolvei, então, que deveríamos fazer pequenas modificações pontuais na aplicação: evitar solicitar muitas consultas diretamente para o servidor, trocando-as por chamadas à stored procedures, limitar a quantidade de linhas retornadas a partir do banco de dados, com a paginação de resultados, e utilização maciça do cachê. Com o uso destas técnicas, conseguimos diminuir em cerca de 60% o consumo de rede, com base na troca de informações entre o servidor de banco de dados e o servidor de aplicações.

    Mais ainda faltava muita coisa para ser feita. Mais especificamente, faltava acertar problemas de desempenho e também a questão da disponibilidade. E, talvez o mais importante, tomar medidas pró-ativas, para evitar que Zé fosse chamado de madrugada para apagar um “incêndio” decorrente de um defeito no ambiente.

    Neste ponto, já revertemos o servidor de banco de dados temporário para o servidor oficial. A partir desta reversão, pude verificar quais são as verdadeiras consultas enviadas pela aplicação em horários de extremo uso (picos de usuários) e nos horários mais folgados. Com base nisso, e também em uma análise do que os usuários mais fazem na aplicação, comecei a esquadrinhar a próximas modificações. Como na maioria das aplicações WEB, os usuários fazem mais visualização de dados do que gravação, isto é, a maioria dos usuários somente joga os produtos no “carrinho” ou apenas os vê, sendo que, em contrapartida, apenas uma pequena parcela dos usuários finaliza as compras e grava dados na base.

    Existem muitas técnicas para otimizar o desempenho. Neste caso específico, o que mais gerou resultados positivos foi a utilização de índices e a re-escrita das consultas da aplicação. Obviamente, antes de começar a fazer os testes verifiquei qual o tempo médio que os usuários gastavam nas operações mais comuns e qual seria o tempo ideal, de acordo com o conhecimento do Zé e de outros especialistas no negócio. Além disso, deixei claro que, para manter o tempo de resposta, verificaria apenas o banco de dados, que na maioria das vezes NÃO é o principal responsável. Esta última frase pode até gerar polêmica, mas eu me reservo no direito de fazer esta afirmação com base na minha experiência em consultoria de banco de dados. Mais uma vez, a idéia aqui não é apontar dedos e procurar culpados, mais sim alertar para os problemas.

    Após resolver os principais problemas, comecei a explicar para o Zé que apenas isso não serie necessário: de nada adiantaria deixar o ambiente limpo, otimizado e controlado se, por algum motivo bobo, tudo fosse água abaixo em um momento de grande utilização. Na área de sistemas, e em particular na parte administrativa, a maioria das pessoas nem lembra que o sistema existe. Porém, é só um pequeno erro aparecer que lá vêm os usuários com dez pedras na mão. Sem contar que quase não há reconhecimento quando tudo funciona corretamente. Mas quando algo, por menor que seja, não funciona como esperado… é melhorar estar preparado, pois alguém, mais cedo ou mais tarde, vai te procurar. E, de acordo com a lei de Murfy que costuma reinar na área de T.I., será no pior momento possível.

    Após deixar este ponto bem claro, comecei a explicar a importância da disponibilidade. Como trabalhamos com máquinas, todos esperam que elas estejam disponíveis 24 horas por dia, nos 365 dias do ano. Infelizmente, para se obter este tipo de disponibilidade, é necessária uma grande quantidade de recursos. Não apenas hardware, como RAID, link de rede redundante, gabinetes com fonte extra etc, mas também na parte de software e de pessoal. Ter a consciência que gastos para se obter uma disponibilidade razoável são necessário é o primeiro passo a ser dado. Ás vezes isso é muito mais uma questão cultural do que técnica, mas esse já é assunto para outro artigo.

    No ambiente do Zé, expliquei quais seriam algumas das ações para garantir o mínimo de disponibilidade. Configurei uma replicação transacional do ambiente de produção para um ambiente de backup. Além disso, mostrei na prática como agir caso algum erro acontecesse. A rede caiu? Faltou força? A HD do servidor ficou sem espaço em disco? Uma fonte do servidor queimou? Cara uma destas situações, e outras mais desastrosas, foram documentadas, priorizadas, organizadas e praticadas, indicando quais os recursos necessários para se resolver o problema, quanto tempo, em média, seria gasto para resolver esta solução e quem seria o responsável por isso. Junto com este documento, e com o treinamento prático, uma lista de responsáveis por manter esta alta disponibilidade foi elaborada.

    Com base em outras soluções técnicas, conseguimos estimar uma disponibilidade aceitável, a partir dos recursos disponíveis. Mais uma vez, deixei claro que, quanto maior for a disponibilidade desejada, mais caro vai sair. Por fim, Zé me fez um elogio, pois ele nunca tinha visto tanta preocupação com a disponibilidade da parte técnica.

    Em seguida, comecei a falta sobre as ações pró-ativas. Este, no meu ponto de vista, é um tópico fundamental para quem trabalha com administração/desenvolvimento. Agir de forma pró-ativa é muito importante pois, caso contrário, é melhor se acostumar a ser chamado de madrugada para apagar incêndios.

    Mais uma vez, saber agir de forma pró-ativa requer ultrapassar uma grande barreira cultural. Aqui devemos combater a máxima: em time que está ganhando não se mexe. Alias, quando ouço isso já me preparo para gastar um bom tempo explicando a necessidade de mudança de atitude.

    Ser pró-ativo significa agir antes do problema. Enxergar depois da curva. Levar o bolo enquanto os outros ainda estão trazendo a farinha. Agindo desta maneira, efetivamente estamos fazendo as máquinas trabalharem para nós e não o contrário.

    Voltando para a consultoria, expliquei para o Zé é que é um Capacity Plan (plano de capacidade) e como montar um. Com as estimativas contidas neste documento, pode-se planejar o consumo futuro de recursos, como quando é necessário adicionar uma nova HD ao servidor. Obviamente, este documento contém apenas algumas estimativas, que devem ser atualizadas periodicamente, e representam apenas um passo inicial.

    Em seguida, a parte prática: configurar auditoria no SQL Server, criar alertas do SQL Server baseados nos marcadores de desempenho do Windows, utilizadas rotinas administrativas periódicas no servidor para limpeza, otimização, organização e coleta de dados, geração automática de relatórios do ambiente (enviadas por e-mail) e criação de uma série de atitudes automáticas que o sistema pode realizar em casos de problemas. Estas tarefas consomem tempos e recursos, mas em situações extremas, é um verdadeiro alívio contar com elas.

    Já estava quase no final da consultoria quando resolvi deixar bem claro para Zé que, apesar de tudo que tínhamos feito, de nada adiantaria a consultoria e as ações tomadas se as práticas não fossem seguidas. O que quis dizer foi o seguinte: Se você deixar o cavalo solto ele vai embora junto com o primeiro que passar. Por isso é importante a atribuição de responsabilidade e o profissionalismo constante, para manter tudo aquilo que foi ganho pelas ações tomadas.

    Acabada a parte técnica, resolvemos fazer uma pequena apresentação para os superiores de Zé, tanto para “mostrar serviço” como para indicar que tudo aquilo não foi feito em vão. Da mesma maneira que no programa “Pimp My Ride”, choviam elogios. Acreditem: mostrar como era antes e como ficou depois possui um grande apelo. E o mais importante de tudo: deixar claro que o que foi feito não é mágica, mas sim o resultado de trabalho duro, dedicação, esforço e muita, mas muita força de vontade para resolver os problemas.

    Um grande abraço e até a próxima coluna.

  • Internet, o mais próspero mercado já criado!

    Muitos profissionais de internet andam preocupados com seus empregos. Fiquem tranquilos, pois o jogo está apenas começando!

    Quando comecei a trabalhar com desenvolvimento, lembro-me que cobrava muito caro por websites ainda muito simples. Conforme o mercado crescia, mais barato tinhamos que cobrar devido ao aumento da competitividade.

    No início de 2007 chegamos a 1 milhão de domínios registrados no Brasil e temos uma média de 30 mil novos domínios a cada mês, segundo registro.br .

    Se fizermos uma análise nos sites brasileiros, podemos perceber que 90% deles ainda estão na primeira geração de sites. Ou seja, subutilizam a Internet, estando apenas como um outdoor ou um cartão de visitas pregados e parados. 8% estão na segunda geração, que por sua vez são mais sofisticados, possuindo certo números de interações, dinamismo, utilização de banco de dados, entre outros. E, finalmente, apenas 2% estão na terceira geração, ou seja, portais de relacionamento que focam na inovação colaborativa, gerando assim uma inteligência coletiva que pode ser utilizada para alavancar qualquer tipo de negócio, projeto, entre outros.

    Segundo Calors Nepomuceno, autor do livro “O conhecimento em rede”, todas as intranets empresariais terão de ser refeitas nos próximos 4 anos. Um antigo conceito está vindo à tona: inteligência coletiva, falada por Pierre Levy, há 15 anos atrás. Agora, com a Internet a todo vapor, isso está acontecendo!

    Muitos devem estar se perguntando aonde eu quero chegar com isso! Minha resposta é a seguinte:

    Da mesma forma que em 1995 eu tinha meu pentium 100 e hoje, 12 anos depois, eu tenho um AMD Turion 64bits, as empresas que desenvolveram seus sites “outdoor” em meados de 2000 terão de refazê-los, mas com um grande diferencial: esses sites terão de ser no mínimo de segunda ou terceira geração!

    Mas como fazer isso?

    Há inúmeras soluções, mas pelo menos o caminho já está traçado: não podemos continuar “vendendo” sites ultrapassados, que não trazem resultados para o cliente. Se o cliente subutilizar o seu próprio site, a Internet vai ser apenas mais um custo para ele e não um próspero investimento. Precisamos dar a gestão pró-ativa de seu portal. Isso não é fácil, mas é necessário, e se você não fizer, pode ter certeza que o concorrente o fará.

  • Sistemas de Apoio à Decisão: Como ajudar os gerentes de TI a tomarem decisões mais confiáveis e embasadas

    Sistemas de Apoio à Decisão: Como ajudar os gerentes de TI a tomarem decisões mais confiáveis e embasadas

    Hoje em dia existem diversos questionamentos a respeito da qualidade da tomada de decisão dos gerentes de Tecnologia da Informação (TI). Pode-se citar o fato de que as empresas pagarem caro pelos re-trabalhos causados pelas decisões tomadas precipitadamente por seus gerentes. É claro que isso acontece na grande maioria das vezes pela falta de suporte à tomada de decisões no meio gerencial, visto que quase não existe software que auxilie no planejamento e organização das tomadas de decisões na área de TI . Sabe-se, ainda, que a inexistência ou a ineficácia do uso de um Sistema de Apoio à Decisão leva, muitas vezes, as empresas a prejuízos incalculáveis, uma vez que o risco de se tomar uma decisão baseada apenas na percepção limitada de cada gerente é muito grande. Contudo, este riso não é apenas financeiro, mas também de âmbito estratégico. As tomadas de decisão apoiadas em um Sistema de Apoio à Decisão (SAD) permitem ao gerente de TI maior segurança para ajudá-lo a perceber, dentre inúmeras escolhas, qual a mais adequada ao seu negócio e às metas de sua empresa.

    LAUDON (2004) afirma que um SAD tem por objetivo auxiliar o processo de decisão gerencial, combinando dados, ferramentas e modelos analíticos sofisticados e software amigável ao usuário em um único e poderoso sistema que pode dar suporte à tomada de decisão semi-estruturada e não-estruturada. Além disso, um SAD fornece aos usuários um conjunto flexível de ferramentas e capacidades para analisar dados importantes.

    Os SADs usam dados fornecidos de outros sistemas, tais como: Sistemas de Processamento de Transações, Sistemas de Trabalhadores do Conhecimento e Sistemas Gerenciais. Porém, as informações produzidas pelos SADs não são baseadas somente nestes sistemas, existem dados provenientes do ambiente externo da organização, como por exemplo: o valor corrente das ações ou os preços dos produtos de concorrentes. Visto isso, é correto dizer que um SAD não só trabalha com dados para ajudar os gerentes a tomarem decisões triviais, mas também será usado principalmente em situações em que for necessário tomar decisões estratégicas para o bom andamento da empresa.

    Existe, hoje em dia, uma carência de Sistema de Informação que atenda às necessidades dos gerentes de TI. Um SAD para gerentes de TI deve disponibilizar funcionalidades para que este gerente possa entrar com dados vindos de outros Sistemas de Informação, fazendo com que os resultados obtidos sejam capazes de maximizar lucros e minimizar custos, fornecendo como retorno um número mínimo de caminhos para que o gerente possa tomar as decisões estratégicas.

    Um objetivo claro dos SADs é atender as necessidades de um gerente de TI quando for tomar decisões não estruturadas, pois a construção de modelos para soluções de problemas pouco tangíveis é de difícil percepção. Pode-se concluir, então, que com um Sistema de Apoio à Decisão é possível esperar o aprimoramento da qualidade das decisões tomadas por gerentes de TI nos diversos âmbitos empresariais.

    Atenção: “As decisões que tomou no passado definiram o que você é hoje, e as decisões que tomar hoje definirão o que você será no futuro”

    Referências Bibliográfica

    LAUDON, K. C., LAUDON, J. P., Sistemas de Informação Gerencias: Administrando a empresa digital. 5. ed. São Paulo. Prentice-Hall, 2004

  • Ajustando o BUFFER CACHE, SHARED POOL e o LOG BUFFER

    Olá a todos. É bem verdade que as interfaces GUI como o Spotlight, o Database/Grid Control(10g), o OEM(9x) entre outras, são muito úteis, e facilitam em muito a identificação de problemas de performance. Mas, como nem sempre teremos essas ferramentas à mão, é interessante saber utilizar as visões V$ para identificar problemas de performance.

    Por isso, nesse artigo iremos falar um pouco da utilização de views para realizar o ajuste do BUFFER CACHE, SHARED POOL e LOG BUFFER.

    BUFFER CACHE

    O buffer cache é utilizado para armazenar os blocos lidos a partir dos discos. Significa que um buffer cache pequeno irá fazer com que o Oracle precise remover do cache os blocos de dados seguindo a lista LRU (LAST RECENTLY USED), e dependendo da frequência com que isso acontece, poderá gerar uma queda na performance.

    Não existe uma mágica para dimensionar o buffer cache, o que normalmente se faz é estimar um tamanho inicial e monitorar o acerto, caso não esteja dentro do ideal, você precisará aumentar e repetir o ciclo de monitoramento.

    Um detalhe importante é que quando a instância é inicializada, o buffer cache está vazio, portanto, qualquer consulta irá gerar misses no buffer. Significa dizer que validar as taxas de acerto no buffer logo após o startup é errado, você provavelmente terá uma taxa de acerto muito baixa.

    O buffer é calculado usando a seguinte fórmula:

    1 – (physical_reads/(db_block_gets consistent_gets))

    consistent gets é o número de vezes que uma leitura consistente foi requisitada para um bloco do buffer cache.

    db block gets from é o número de vezes que um bloco foi requisitado para o buffer cache.

    physical reads é o número total de blocos de dados lidos do disco para o buffer cache.

    SELECT NAME, PHYSICAL_READS, DB_BLOCK_GETS, CONSISTENT_GETS,
           1 - (PHYSICAL_READS / (DB_BLOCK_GETS  CONSISTENT_GETS)) "Hit Ratio"
    FROM VBUFFER_POOL_STATISTICS;
    
    NAME            PHYSICAL_READS DB_BLOCK_GETS CONSISTENT_GETS  Hit Ratio
    --------------- -------------- ------------- --------------- ----------
    DEFAULT                2382927      85639921        46004325 .981898738
    
    1 row selected.

    No exemplo acima, a taxa de acerto foi de 98 no buffer cache.

    Uma consulta semelhante pode ser feita na VSYSSTAT:

    SELECT NAME, VALUE
    FROM VSYSSTAT
    WHERE NAME IN ('db block gets from cache', 
                   'consistent gets from cache', 
                   'physical reads cache');
    
    NAME                                                VALUE
    ---------------------------------------------- ----------
    db block gets from cache                         88204118
    consistent gets from cache                     9726193722
    physical reads cache                              2560965
    
    3 rows selected.

    1 – (2560965/(882041189726193722)) = 0,99973906

    O buffer cache também pode ser ajustado com base na view VDB_CACHE_ADVICE.

    Para que essa view seja populada é necessário que o parâmetro DB_CACHE_ADVICE esteja ON.

    show parameter db_cache_advice
    db_cache_advice                      string   ON

    A declaração abaixo consulta a respectiva view, retornando estimativas de buffer e de acerto.

    COLUMN size_for_estimate FORMAT 999,999,999,999 heading 'Cache Size (MB)'
    COLUMN buffers_for_estimate FORMAT 999,999,999 heading 'Buffers'
    COLUMN estd_physical_read_factor FORMAT 999.90 heading 'Estd PhysRead Factor'
    COLUMN estd_physical_reads FORMAT 999,999,999 heading 'Estd Phys Reads'
    
    SELECT size_for_estimate, buffers_for_estimate, 
           estd_physical_read_factor, estd_physical_reads
      FROM VDB_CACHE_ADVICE
     WHERE name = 'DEFAULT'
       AND block_size = (SELECT value 
                           FROM VPARAMETER 
        			      WHERE name = 'db_block_size')
       AND advice_status = 'ON';
    
                                    Estd Phys    Estd Phys
     Cache Size (MB)      Buffers Read Factor        Reads
    ---------------- ------------ ----------- ------------
                  80        9,915       61.70  150,251,109
                 160       19,830       40.30   98,140,104
                 240       29,745       21.08   51,329,557
                 320       39,660        7.23   17,594,710
                 400       49,575        1.36    3,309,722
                 480       59,490        1.21    2,948,364
                 560       69,405        1.13    2,763,717
                 640       79,320        1.09    2,655,866
                 720       89,235        1.06    2,581,271
                 800       99,150        1.03    2,510,199
                 880      109,065        1.00    2,435,219
                 960      118,980         .98    2,380,060
               1,040      128,895         .97    2,350,269
               1,120      138,810         .95    2,309,334
               1,200      148,725         .93    2,275,624
               1,280      158,640         .92    2,249,930
               1,360      168,555         .92    2,231,580
               1,440      178,470         .91    2,211,413
               1,520      188,385         .90    2,193,922
               1,600      198,300         .89    2,167,724
    
    20 rows selected.

    A análise dela é feita de forma diferente a de taxas. A consulta mostra uma redução de 2(0.98) no número de leitura físicas caso o buffer cache seja configurado para 960MB.

    Lembrando que, quando falamos de memória, estamos falando de memória física, um servidor Oracle, não deve fazer swap.

    Para utilizar o buffer cache de forma eficiente, as declarações SQL da aplicação devem estar ajustadas para evitar consumo desnecessário de recursos. Isso é feito verificando as declarações SQL executadas com mais freqência e as que fazem uso de uma maior quantidade de buffers.

    A consulta abaixo retorna as 50 maiores consultas consumidoras de BUFFERS.

    SELECT *
    FROM (SELECT SQL_FULLTEXT, BUFFER_GETS
            FROM VSQL
           ORDER BY BUFFER_GETS DESC)
    WHERE ROWNUM <= 50

    Existem duas formas de melhorar o acerto no buffer:

    • Otimizando as consultas de forma a retornarem menos blocos, e dessa forma utilizar menos buffer.
    • Aumentando o buffer cache.
    SHARED POOL

    O Oracle utilize a SHARED POOL para armazenar declarações PL/SQL e SQL, dados do dicionário entre outros.

    Da mesma forma que o BUFFER CACHE, é impossível determinar um tamanho inicial para uma base nova. Você deve seguir o mesmo principio do BUFFER CACHE, colocar um valor e avaliar o ambiente. Lembrando que a SHARED POOL inicia vazia, e à medida que os usuários vão submetendo as declarações SQL ela vai sendo preenchida.

    Para isso, observe o seguinte:

    • Utilize sempre que possível bind variables ao invés de caracteres literais nas declarações. Isso faz com que o Oracle armazene apenas uma declaração SQL. As declarações, apesar de semelhantes, ocupam duas áreas distintas na SHARED_POOL:

    Substitua:

    SELECT employee_id FROM employees WHERE department_id = 10;
    SELECT employee_id FROM employees WHERE department_id = 20;

    Por:

    SELECT employee_id FROM employees WHERE department_id = :dept_id;
    • As aplicações devem evitar os usuários possam criar suas próprias instruções.
    • Crie padrões para as bind variables e para os espaços nas declarações SQL blocos de PL/SQL.

    Por exemplo:

    SELECT employee_id FROM employees WHERE department_id = :dept_id

    É diferente de:

    SELECT employee_id FROM employees where department_id = :dept_id

    O objetivo do tuning na SHARED_POOL é fazer com que uma declaração SQL que está no cache possa ser reutilizada o maior número de vezes possível.

    Utilize a declaração abaixo para identificar a taxa de hit ratio da shared pool:

    SELECT sum(pinhits) / sum(pins)
    FROM VLIBRARYCACHE;
    
    SUM(PINHITS)/SUM(PINS)
    ---------------------- 
                .996986356
    
    1 row selected.

    A consulta mostrou que 99,69 dos códigos de SQL e PLSQL estão sendo reaproveitados.

    A declaração abaixo mostra a quantidade de bytes livres na SHARED_POOL.

    SELECT * FROM VSGASTAT
    WHERE NAME = 'free memory'
    AND POOL = 'shared pool';
    
    POOL         NAME                          BYTES
    -----------  ------------------------- ---------
    shared pool  free memory               385236520
    
    1 row selected.

    A consulta abaixo também auxilia na descoberta da taxa de acerto da SHARED POOL.

    SELECT (SUM(GETS - GETMISSES - FIXED)) / SUM(GETS) "ROW CACHE" 
    FROM VROWCACHE;
    
     ROW CACHE
    ----------
    .994562437
    
    1 row selected.

    Também é possível utilizar a view VSHARED_POOL_ADVICE. Para isso é preciso que o parâmetro STATISTICS_LEVEL esteja configurado como ALL ou TYPICAL.

    show parameter statistics_level;
    
    statistics_level                     string   TYPICAL
    SELECT shared_pool_size_for_estimate "Size of Shared Pool in MB",
           shared_pool_size_factor "Size Factor",
           estd_lc_time_saved "Time Saved in sec"
      FROM vshared_pool_advice;
    
    Size of Shared Pool in MB Size Factor Time Saved in sec
    ------------------------- ----------- -----------------
                          352       .2391           1461671
                          512       .3478           1465054
                          672       .4565           1470451
                          832       .5652           1472452
                          992       .6739           1472513
                         1152       .7826           1472536
                         1312       .8913           1472542
                         1472           1           1472542
                         1632      1.1087           1472542
                         1792      1.2174           1472542
                         1952      1.3261           1472542
                         2112      1.4348           1472542
                         2272      1.5435           1472542
                         2432      1.6522           1472542
                         2592      1.7609           1472542
                         2752      1.8696           1472542
                         2912      1.9783           1472542
                         3072       2.087           1472542
    
    18 rows selected.

    A saída acima mostra que o tamanho da shared pool é de 1472M. Mostra também que, se o tamanho da shared pool fosse ajustado para 3072M, teria a mesma eficiência.

    LOG BUFFER

    Aplicações que inserem, modificam ou excluem um grande volume de registros normalmente não utilizam o tamanho default de log buffer. Apesar do tamanho do log buffer ser bem menor frente ao tamanho total da SGA, ele tem grande impacto na performace de sistemas que realizam atualização no volume dos dados.

    Um tamanho inicial para o log buffer é:

    MAX(0.5M, (128K * número de CPUs))

    A maioria dos sistemas que possuem log buffer maior que 1M não possuem ganhos de performance.

    A análise da performance do log buffer é feita por intervalo. Deve ser coletado em intervalos, e verificar se existe um aumento do valor. O ideal é que não existam alterações.

    SELECT NAME, VALUE
    FROM VSYSSTAT
    WHERE NAME = 'redo buffer allocation retries';
    
    NAME                                                             VALUE
    ----------------------------------------------------------- ----------
    redo buffer allocation retries                                      11
    
    1 row selected.

    Se o valor aumentar de forma consistente, é necessário ajustar o tamanho do log buffer.

    Esse artigo forneceu uma forma básica de verificação da performance do database. É preciso levar em consideração que, mesmo com todas as taxas próximas a 100, é possível que outros fatores como I/O ou CPU estejam comprometendo a performance. Abordaremos esses problemas e como identificar através de visões no próximo artigo.

    Bons Tunings!

  • Gerenciamento ou Governança de TI?

    “Que COBIT que nada!”

    Seguindo a escola do CIO da Rodhia mundial Xavir Rambaud, que “desdenhou” do ITIL(1), para todo mundo ouvir, este texto faz uma reflexão sobre Governança de TI.

    Uma vez que Gerenciamento de TI está focado no presente e no interno e a Governança de TI está no externo e no futuro(2), os problemas das áreas de TI “bagunçadas” devem ser resolvidos com Gerenciamento enquanto problemas com gestores, ou demandantes, que “não sabem o que querem” devem ser resolvidos com Governança de TI.

    No uso do COBIT 4.0 com seus 34 processos, a Organização poderia se concentrar em alguns deles e resolver de vez a questão de quem decide o que em relação a TI. Os processos que efetivamente podem lidar com os custos envolvidos para as soluções (sistemas) são:

    • PO 1.1 Gestão do Valor da TI
    • PO 4 Processos, Organização e Relacionamento
    • O Verificar quase todos os Fatores Críticos de Sucesso (FCS).
    • PO 5 Investimentos em TI
    • DS 1 Definição e gestão dos níveis de serviços.
    • O Verificar o FCS A organização de TI pode identificar as fontes de discordâncias de custos.
    • DS 6 Identificar e alocar Custos de TI.
    • ME 4.4 Gerenciamento de Recursos

    Atualmente, os centros de TI têm seus custos rateados pelo total com todas as demais unidades, tudo é um bolo só. Ou, o orçamento de TI é definido pelo histórico e desejos dos executivos da área, costuma ser um dos maiores causando espanto, indignação e um sentimento de que o pessoal da TI custa muito caro, ou é improdutivo, ou desperdiça demais (3).

    Se a organização conseguir mapear e distribuir os custos que cada produto gera para a área de TI (Gerenciamento) pode-se resolver o problema dos orçamentos e de quem manda nas aquisições, ou desenvolvimentos (Governança).

    Por exemplo, a partir do momento que a área de RH começar a pagar, e ter noção do custo, pelo processamento e manutenção da folha de pagamento e seus aderentes, mais da metade das preocupações da teoria da Governança de TI se resolverão. O problema de se atribuir custo aos processos de TI, do ponto de vista técnico, são muito mais fáceis do que do ponto de vista político.

    Quando a organização perceber que algumas áreas que não trazem contribuição (o que não é o caso da RH), ou não se justificam, para os negócios, o ônus de explicar custos e orçamentos recai sobre as mesmas. Isso pode ser muito pedagógico evitando que essas áreas demandem coisas pouco sustentáveis em comparação com outras áreas

    Até que a empresa resolva encarar para valer o gerenciamento global de custos de processamento, uma dica sustentada pela Governança de TI em seu modelo Federalista(4), é criar os comitês gestores com a participação de todos os executivos corporativos. Pessimismos à parte, o máximo que pode acontecer com um grupo destes é que aqueles que choram ou esperneiam mais consigam convencer os outros sobre SUAS necessidades e não as necessidades da organização.

    Enfim, o Gerenciamento de TI, que só a área de TI sabe, ou pode fazer, poderia sugerir à Governança de TI, que ainda não se sabe quem entende disso, adote como premissa básica ter os custos envolvidos com o processamento dos sistemas de cada stakeholder muito bem definido. E, se a Governança conseguisse que os demandantes de TI comprovassem o quanto cada sistema sob sua responsabilidade traz de retorno para a organização, teríamos menos discussões, conflitos e aborrecimento entre as áreas em relação a TI. Talvez tivéssemos mais gente triste, mas por outros motivos.

    Concluindo, não há novidade alguma em administrar recursos sob o ponto de vista de custo e retorno. Isso é uma preocupação antiga, tão antiga quanto as Teorias Gerais de Administração (TGA). A maneira mais eficiente de se fazer com que atores desempenhem com responsabilidade, interesse, eficiência, etc., seus papéis é forçá-los a pagar por isso. Alguém duvida? Então, num esforço transdiciplinar, aproveite e estude um pouco sobre Responsabilidade Socioambiental, especificamente a legislação ambiental sobre o Princípio do Pagador Poluidor que “obrigaria” os poluidores a pagarem pelos estragos ao meio ambiente.

    Fonte

    • Reportagem “Que ITIL que nada”, revista Info Corporate, Dez/2006, p.82
    • Van Grembergen, W. Strategies for information technology governance. Hershey: Idea Group Pub., 2003 cap. 2 de Ryan R. Peterson.
    • Mattos A.C.M. Sistemas de Informação uma visão executiva. Ed. Saraiva, 2005, pág. 159-164.
    • Weill Ross. Governança de TI: São Paulo: M.Books do Brasil, 2006, pág. 60-61.
  • Carregar novo link numa textArea

    Olá gente! Antes de mais nada, quero agradecer pelos e-mails que tenho recebido. Desejo que essas dicas possam ajudá-los nos seus trabalhos.

    Esta matéria está relacionada a uma dificuldade que enfrentei tempos atrás. É algo simples, mas para quem administra uma intranet ou até mesmo um site mais complexo pode ajudar muito.

    Como os administradores de conteúdo das intranets nas empresas não têm tanto conhecimento em html, uma das nossas tarefas como desenvolvedor de soluções é facilitar ao máximo o trabalho deste pessoal.

    Uma das necessidades que percebi foi como relacionar uma nova publicação com algo que já existe no banco, como por exemplo, uma galeria de fotos.

    Neste exemplo, será mostrado como fazer para, a partir de uma lista de galeria, o administrador escolha uma, ou mais, e cria um link direcionando para seu conteúdo.

    Vejam as imagens abaixo:

    Bom, essa é uma notícia que espero que aconteça… ou outra melhor!!!

    Após a descrição da notícia, o administrador do sistema precisa colocar um link para a galeria de fotos. A melhor forma para isso foi abrir uma janela que visualizar todas as galerias. A partir desta lista, o administrador escolhe uma e a aplicação já cria um link para o seu conteúdo, como segue:

    Como existem vários arquivos para compor esse artigo, além da textArea html (que vai de lambuja), baixe-os acessando: http://www.ricarela.com/artigos/publica002.zip.

    Qualquer coisa é só entrar em contato.

    Aquele abraço e fiquem com Deus!!!

    E dá-lhe, Ponte!!!

  • Região de Nova York tem mais empregos de TI que Vale do Silício

    São 12,3 mil postos de trabalho contra 9,3 mil

    A região de Nova York e Nova Jersey dispõe de mais oportunidades de empregos para profissionais de TI do que o Vale do Silício, na Califórnia (EUA), segundo pesquisa da Dice, consultoria de carreira da área de tecnologia.

    Segundo o levantamento, são 12,3 mil posições de trabalho disponíveis na área da cidade de Nova York, Long Island e norte de Nova Jersey. Já na região do Vale do Silício são 9,3 mil empregos, incluindo São Francisco, São José e Oakland.

    Washington, a capital norte-americana, vem logo em seguida, com 7,7 mil oportunidades para profissionais de TI. Completam a lista das 10 cidades dos EUA com maior número de empregos em TI: Los Angeles (6,6 mil); Chicago (4,2 mil); Philadelphia (3,7 mil); Boston (3,7 mil); Dallas (3 mil); Atlanta (2,7 mil) e Seattle (2,2 mil).