Image Image Image Image Image
Scroll to Top

Topo

SQL

27

mar
2012

Sem Comentários

Em Blog
SQL

Por Allison

SQL Server 2012: Grandes melhorias no T-SQL

Em 27, mar 2012 | Sem Comentários | Em Blog, SQL | Por Allison

Fonte: Jonathan Allen , traduzido por Mário Henrique/InfoQ

O dialeto SQL do SQL Server 2012, o Transact-SQL, vem com melhorias importantes, incluindo suporte para funções ANSI FIRST_VALUE e LAST_VALUE, paginação de resultados de alto nível usando FETCH e OFFSET e suporte a funções de parsing e de formatação do .NET.

Fetch e Offset

Atualmente, muitos desenvolvedores de SQL Server que desejam implementar paginação de resultados no lado do servidor precisam utilizar técnicas “imperativas” de programação, como carregar os resultados em uma tabela temporária, numerar as linhas e então selecionar o intervalo de interesse. Há também desenvolvedores que utilizam ROW NUMBER e OVER; outros utilizam cursores.

O SQL Server 2012 resolve essa limitação e permite mais consistência no uso, adicionando suporte declarativo para a paginação de resultados, através das novas opções OFFSET e FETCH NEXT do Transact-SQL. Mas note que atualmente não há otimização de performance; o SQL Server está fazendo a mesma coisa que os desenvolvedores fariam manualmente.

Clause Windowing

Às vezes, os desenvolvedores precisam escrever consultas que identificam diferenças entre linhas. Por exemplo, pode-se estar interessado na quantidade de tempo entre o timestamp de uma linha e outra. Isso é fácil de fazer utilizando cursores, mas o desempenho e elegância dessa solução deixam a desejar. É possível ainda utilizar uma subquery executada linha a linha, mas isso é extremamente custoso. Pode-se ainda implementar tudo no lado do cliente mas isso não funcionaria se o cliente for uma ferramenta de geração de relatórios, por exemplo.

No SQL Server 2012, agora é possível acessar diretamente a linha anterior utilizando a função LAG. O analisador de consultas SQL retém a linha anterior na memória, de forma que não há necessidade de uma subquery. Isso resulta em melhor desempenho. A função LAG aponta para a linha anterior, mas é possível utilizar um offset para ter acesso a linhas anteriores. A função LEAD é equivalente a LAG, mas trabalha com linhas posteriores à que está sendo lida. As funções LAG e LEAD, que são parte do padrão ANSI, eram um pedidas pelos desenvolvedores desde a implementação da sintaxe OVER no SQL Server 2005. As funções FIRST VALUE e LAST VALUE também estão disponíveis no SQL Server 2012.

Reflection

Anteriormente, para testar quais os resultados seriam retornados por stored procedures ou consultas SQL, utilizava-se o comando SET FMTONLY. Esse comando permitia aos desenvolvedores visualizar as colunas retornadas, sem a necessidade de executar uma consulta SQL. Mas a informação se limitava apenas às definições das colunas resultantes da execução da consulta.

Com a nova procedure sp describe first result set, os desenvolvedores podem obter informações detalhadas a respeito de quais resultados seriam retornados pela consulta. Essas informações incluem tipos de dados, tabelas ou colunas-fonte e outras informações importantes, também disponíveis nas telas de gerenciamento dinâmico, sys.dm exec describe first result e sys.dm exec describe first result set.

Código Defensivo

Tradicionalmente, os desenvolvedores ficam à mercê de seus colegas quando utilizam stored procedures. Sem garantias em relação ao que será retornado, falhas acidentais se tornam uma preocupação. O T-SQL não oferece formas de prevenir esses erros, mas é possível minimizá-los utilizando a opção RESULT SETS.

Quando usada, a opção RESULT SETS faz com que a procedure armazenada retorne uma estrutura específica de dados. Se os resultados da procedure forem diferentes do requisitado, a opção retorna um erro. Considerando que se trata de um erro em tempo de de execução, recomenda-se aos desenvolvedores que utilizarem essa opção se assegurem de que os erros sejam depurados antes do código ir para produção.

Tratamento de Erros

O T-SQL tem suporte para TRY-CATCH desde 2005, porém o suporte THROW não existia até agora. Sem argumentos, THROW funciona da mesma maneira que em C# ou VB. Isto é, THROW retorna uma exceção e mantém o log de informação capturada sobre o erro, o que é muito útil.

Quando utilizada com argumentos, THROW é similar à RAISERROR, exceto por não suportar números de erros em sys.messages e a severidade é sempre 16. Além disso, os erros não detectados por THROW sempre terminam a execução.

Parsing e Conversões

O T-SQL agora suporta a função PARSE que inclui a opção de especificar uma “culture”. Esta deve contar com suporte pelo framework .NET. Há também uma nova função TRY_CONVERT que, assim como TRY_PARSE, retorna null quando a conversão falha. Já a função FORMAT utiliza a formatação de strings do .NET. Apesar de mais lenta que as funções nativas como STR, é mais flexível.

Funções de Data e Hora

O processamento de data e hora no T-SQL recebeu melhorias. A função EOMONTH retorna o último dia do mês, dado importante para relatórios. As funções xxxFROMPARTS permitem construir valores de data/hora utilizando um conjunto de parâmetro em vez de apenas uma string. Há suporte para os tipos de dados Date, DateTime, DateTime2, DateTimeOffset, SmallDate e Time.

Outras funções

A função Choose do Access e Visual Basic agora está presente no T-SQL. Sob determinadas circunstâncias, pode ser utilizada como uma versão simplificada de CASE. Também está presente a função IIF.

A função CONCAT pode ser utilizada para concatenar strings. Além de tornar mais fácil a portabilidade de código de outras linguagens, essa função possui um tratamento de exceção diferente do operador +. Itzik Ben-Gan escreve:

O operador + de concatenação devolve NULL para inputs NULL. A função CONCAT converte inputs NULL em strings vazias antes da concatenação. Embora esta não seja uma boa solução, é possível fazer a mesma coisa utilizando a função COLAESCE, substituindo entradas NULL por strings vazias.

Tags | , , , ,

19

mar
2012

Sem Comentários

Em Blog
SQL

Por Allison

Microsoft disponibiliza SQL Server 2012 RC0

Em 19, mar 2012 | Sem Comentários | Em Blog, SQL | Por Allison

Com informações de Porta 25

Fonte: IMasters

A Microsoft disponibilizou o SQL Server 2012 RC0, que já pode ser baixado no site oficial do SQL Server 2012. A liberação ocorreu cinco meses depois do TechEd 2011, quando a empresa convidou desenvolvedores e profissionais de TI a fazerem o download do CTP3 do SQL Server 2012, de codinome Denali.

O SQL Server 2012 viabiliza uma plataforma de informação pronta para a nuvem, capaz de ajudar as organizações a tirar melhor proveito de informações extraídas de dados estruturados, não-estruturados e de fontes de dados em cloud gerenciadas por um serviço de BI gerenciado pelo próprio usuário.

Além disso, ele traz novas ferramentas para desenvolvedores, recursos para otimização do seu uso em cloud pública ou privada, novos recursos de relatórios, melhorias nas ferramentas de integração de dados com qualquer tipo de fonte para análises de business intelligence, entre outras novidades.

A versão final do produto será lançada ainda neste semestre, e a Microsoft realiza um evento online no dia 7 de março para detalhar melhor as inovações do lançamento.

Tags | , , ,

16

fev
2012

Sem Comentários

Em Blog
Dados
SQL

Por Allison

Atualização do MySQL Cluster traz melhoria de desempenho

Em 16, fev 2012 | Sem Comentários | Em Blog, Dados, SQL | Por Allison

Com informações de The H

Fonte: IMasters

A Oracle liberou a versão 7.2 do MySQL Cluster, que aumenta consideravelmente a velocidade do banco de dados em rede. Segundo a empresa, a funcionalidade “Adaptive Query Localisation” permite que o cluster responda a consultas mais de 70 vezes mais rápido.

A ideia por trás dessa funcionalidade é que, em vez de deixar todo o processamento de consultas para o servidor central, os nós de dados individuais agora possuem inteligência suficiente para responder a partes das consultas. Isso reduz a quantidade de dados que é enviada para o servidor. A tecnologia é voltada para aumentar a velocidade de consultas que combinam várias tabelas usando JOIN.

Além disso, a memcached API também foi adicionada à nova versão. Isso permite que bancos de dados sejam endereçados como tabelas relacionais através do SQL e como dados key/value no NoSQL. Agora, clusters em diferentes locais físicos podem ser interconectados, e as tabelas comuns de privilégios do usuário foram consolidadas.

O MySQL Cluster 7.2.4 está disponível para download para várias distribuições Linux, Windows e Solaris. Um vídeo sobre o MySQL Cluster pode ser assistido aqui.

Tags | , , , ,

06

fev
2012

Sem Comentários

Em Blog
SQL

Por Allison

SQLol 0.3.1 é disponibilizado

Em 06, fev 2012 | Sem Comentários | Em Blog, SQL | Por Allison

Com informações de Under-Linux

Fonte: IMasters

A versão 0.3.1 do SQLol foi liberada. Ele é um utilitário de segurança, altamente configurável desenvolvido para “testbed” de injeção SQL. Ele permite que o usuário explore falhas de injeção de SQL e uma grande quantidade de controle sobre a manifestação da vulnerabilidade com a qual estiver trabalhando. O SQLol também vem com um conjunto de desafios, relacionados a tarefas que realizem algum tipo de injeção de SQL.

Na nova versão, a 0.3.1, que vem sob o nome de código “Hello My Future Girlfriend Edition”, houve a remoção da funcionalidade para a apresentação de valores via GET / POST cookie. Além disso, a injeção via GET / POST / Cookie deve funcionar independentemente, devido ao uso de $ _REQUEST; mudança do arquivo moreChanged database config, para utilizar o padrão MySQL e localização por default.

O SQLol está hospedado no Github e disponível para download.

Tags | , , ,

31

jan
2012

Sem Comentários

Em Blog
Cloud Computing
SQL

Por Allison

Banco de dados na nuvem do PostgreSQL é anunciado

Em 31, jan 2012 | Sem Comentários | Em Blog, Cloud Computing, SQL | Por Allison

Com informações de The H

Fonte: IMasters

A EnterpriseDB, especialista em PostgreSQL, anunciou a disponibilidade do Postgres Plus Cloud Database no Amazon Web Services (AWS). Agora, usuários podem executar o PostgreSQL ou o PostgreSQL baseado no Postgres Plus Advanced Server com o serviço em nuvem database-as-a-service (DBaaS) sem a necessidade de realizar uma maior instalação ou configuração.

O produto irá rodar no Cloud Compute da HP, que usa a plataforma e a API OpenStack Nova, assim como o Amazon EC2.

A administração será realizada via interface web, e a EnterpriseDB promete alta disponibilidade, autoprovisionamento, backups automáticos e equilíbrio no carregamento automático.

Segundo a EnterpriseDB, as cobranças pelo uso do serviço serão as mesmas feitas pelo baseado em MySQL da Amazon – Relational Database Service (Amazon RDS).

Tags | , ,

05

jan
2012

Sem Comentários

Em Blog
SQL

Por Allison

Uma tabela de relacionamento de muitos para muitos – resolvendo o problema de relação de exclusão

Em 05, jan 2012 | Sem Comentários | Em Blog, SQL | Por Allison

Começarei definindo o relacionamento de Muitos para Muitos MySQL (Experts podem pular para o próximo parágrafo).

O que é um relacionamento de Muitos para Muitos MySQL

Um relacionamento de Muitos para Muitos MySQL é um relacionamento que é multi-valorado em ambas as direções.

Esse tipo de relacionamento é auxiliado pelo uso de uma tabela de ligação. Por exemplo, uma Pergunta (Question) pode ter mais de uma Categoria (Categorie), e uma Categoria pode ter mais de uma Pergunta.

CREATE TABLE link (
   Question_id int unsigned NOT NULL,
   Category varchar(20),
   PRIMARY KEY  (`Question_id `,` Category`),
   KEY `category_question` (`Category`,`Question_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

+-------------+---------------+
| Question_id | Category      |
+-------------+---------------+
|  1          | Animals       |
|  1          | Business      |
|  1          | Vehicles      |
|  2          | Animals       |
|  3          | Business      |
|  3          | Vehicles      |
|  4          | Animals       |
|  4          | Vehicles      |
|  5          | Business      |
+-------------+---------------+

Essa é uma tabela de ligação chamada link, que nos ajuda a juntar relacionamentos entre as duas tabelas, Perguntas e Categorias.

Como podemos ver, essa tabela está refletindo um relacionamento de muitos para muitos (a pergunta 1 tem as categorias Animais, Negócios e Veículos – ‘Animals, Business and Vehicles’. A categoria Animais tem as perguntas 1, 2 e 4).

O que é o problema de relação de exclusão?

Dada uma tabela de relacionamento de muitos para muitos, como você é capaz de selecionar linhas que não tenham um relacionamento específico? Em termos do exemplo pergunta-categoria, essa pergunta é traduzida no seguinte:

Como você consegue selecionar (digamos as primeiras mil) perguntas que não têm a categoria Negócios. No nosso exemplo, queremos somente que os Question_id 2 e 4 sejam retornados.

Uma solução ruim

Uma solução ruim seria:

SELECT
DISTINCT Question_id
FROM
link
WHERE
Category <> "Business"
ORDER BY
Question_id DESC
LIMIT
1000;

Essa consulta irá funcionar se uma pergunta somente for permitida uma categoria. No nosso caso, como uma pergunta tem pelo menos uma categoria, desde que uma pergunta esteja associada à outra categoria que não seja Business, ela retornará. Portanto, o resultado dessa consulta é Question_id: 1, 2, 3, e 4 , que não satisfaz a relação de exclusão.

Primeira solução

SELECT
DISTINCT Question_id
FROM
link
WHERE
Question_id NOT IN (SELECT Question_id FROM link WHERE Category="Business")
ORDER BY
Question_id DESC
LIMIT
1000;

A consulta dependente interna (SELECT Question_id FROM link WHERE Category<>”Business”) tem um problema de desempenho – ela será executada pela menos mil vezes e, se ela não for rápida, os atrasos são multiplicados por um número que é, no mínimo, 1.000. Quando o método de acesso (o type field no EXPLAIN statement output) é index_subquery, um index de pesquisa de otimização é usado e um monte de sobrecarga é evitada.

Quando é ampla, a sub query está sendo reexecutada, como é feita para cada linha. Você deve verificar seus . You must check your EXPLAIN details.

Segunda solução

CREATE TEMPORARY TABLE not_wanted_Question_id (
UNIQUE KEY(Question_id)
) ENGINE=MEMORY
SELECT
DISTINCT Question_id
FROM
link
WHERE
Category="Business";

SELECT
DISTINCT link.Question_id
FROM
link
LEFT JOIN
not_wanted_Question_id nw ON (link.Question_id = nw.Question_id)
WHERE
nw.Question_id is NULL
ORDER BY
link.Question_id DESC
LIMIT
1000;

DROP TABLE not_wanted_Question_id;

O problema de execução de consultas internas múltiplas é reduzido a uma pesquisa uma única chave dentro de uma tabela na memória, que é basicamente uma pesquisa hash e é muito rápida. No entanto, a construção de perguntas indesejadas pode sair caro para tabelas grandes. Note que criar a tabela, selecionar e então soltar devem ser todos feitos juntos, para toda vez que você precisar dos resultados.

Terceira solução (a melhor em desempenho)

Esta é minha melhor solução para esse problema e com melhor desempenho para tabelas pesadas:

SELECT
 Question_id ,
 SUM(IF (Category="Business", 1, 0)) AS exclude
 FROM
 link
 GROUP BY
 Question_id DESC
 HAVING
 exclude=0
 LIMIT
 10000;

Isso funciona muito bem no nosso caso, porque temos um index no Question_id e colunas de categorias. A função SUM está contando o número de ocorrências indesejadas de categoria para cada Question_id na ordem e o statement Having está filtrando-os.

O LIMIT termina os cálculos assim que chega no número limite.

Texto original em ingles de Hazan Ilan, disponível em http://www.mysqldiary.com/a-many-to-many-relationship-table-solving-the-exclude-relation-problem/

Fonte: Hazan Ilan/IMasters

Tags | , , , , ,

23

nov
2011

Sem Comentários

Em Blog
SQL

Por Allison

10 técnicas para otimização de instruções SQL

Em 23, nov 2011 | Sem Comentários | Em Blog, SQL | Por Allison

Neste artigo vou apresentar dez técnicas de otimização de instruções SQL. Elas não são específicas de um banco de dados e podem ser aplicadas em qualquer SGBD que utilize SQL e até bancos de dados NoSQL.

Também destaco que estas são apenas sugestões de técnicas que podem ser aplicadas, pois o processo de tuning de instruções SQL, ou seja, otimizar uma instrução para que ela seja executada mais rapidamente, é complexo, demorado, depende de cada cenário e exige uma boa dose de experiência. Contudo, quanto mais nos esforçarmos e focarmos na otimização, melhores serão os resultados.

Outro ponto importante, que é preciso destacar, é que estas técnicas podem ser aplicadas às quatro principais instruções SQL: SELECT, INSERT, UPDATE e DELETE. Como dito anteriormente, algumas delas também são válidas para os bancos de dados NoSQL, um vez que, apesar da linguagem SQL não ser empregada, muitos dos conceitos são os mesmos (geração de plano de execução, uso de índices, métricas, etc).

1. Use bem os índices

Um dos principais fatores que impacta no desempenho de uma instrução SQL é o uso de índices, principalmente em instruções que empregam tabelas com muitos dados. Este é um fator tão importante, que a mera criação de um índice pode reduzir drasticamente a quantidade de passos internos na execução de instruções SQL.

Neste momento surge uma pergunta: como começar a analisar e criar os índices adequados? Infelizmente, não existe uma única resposta para esta pergunta. Mas para ajudar o leitor que não tem muita experiência no uso de índices, montei o seguinte fluxograma apresentado abaixo. Este diagrama é apenas uma sugestão genérica e deve ser utilizado somente como ponto de partida para aqueles que possuem pouca experiência. Obviamente, a cada criação de índice devem ser realizados diversos testes.

2. Explore o paralelismo

Atualmente, vivemos em uma era onde os microprocessadores são dominados por múltiplos núcleos. Até dispositivos móveis como smartphones, tablets e consoles portáteis estão recebendo microprocessadores com múltiplos núcleos. Mas isso não quer dizer que as aplicações estejam preparadas para obter o máximo de desempenho proporcionado por este hardware.

Sendo assim, é recomendável sempre procurar explorar o paralelismo em banco de dados. Apesar desta preocupação ser relativamente recente, e talvez um pouco mais comum para quem trabalha com programação, a exploração de paralelismo deve ser considerada quando for necessário otimizar instruções SQL.

Infelizmente, existem poucos recursos para a manipulação, ou aplicação direta de conceitos de programação paralela direto no banco de dados. Entretanto, é possível utilizar algumas técnicas para explorar o paralelismo na execução de instruções SQL,. dependendo, principalmente, do banco de dados a ser utilizado. Por exemplo: tanto o Oracle, quanto o SQL Server possuem diversos operadores utilizados internamente no plano de execução para mostrar se o plano escolhido utilizou, ou não paralelismo. Outro exemplo é a técnica apresentada no meu artigo de capa da revista SQL Magazine número 91, chamado Processamento paralelo de instruções SQL, disponível em neste aqui.

3. Saiba trabalhar com condições de pesquisa dinâmica

Imagine a seguinte situação: uma aplicação permite ao usuário escolher diversos campos para pesquisar na base de dados. Estes campos são apresentados através de elementos de um formulário como campos de texto, checkbox, combo e outros. Se o valor de algum campo for preenchido, este valor será montado em uma string, cujo conteúdo será utilizado para montar uma cláusula WHERE na instrução SELECT, que será encaminhada para o banco de dados. Este cenário é muito comum tanto em aplicações desktop, como em aplicações web.

Deixando as preocupações com SQL Injection de lado, como garantir que instruções SELECT dinâmicas possam ser executadas com um bom desempenho? Bem, como esta situação é muito comum, há uma técnica chamada condições de pesquisa dinâmica que pode auxiliar a criação da instrução SELECT visando tanto a flexibilidade proporcionada pela escolha dinâmica de filtros, quanto pelo desempenho.

Para quem trabalha com o SQL Server, existe alguns artigos escritos por Erland Sommarskog e que abordam esta técnica. Eles estão disponíveis neste link. Os conceitos apresentados podem ser adaptados para outros bancos de dados sem grandes problemas.

4. Conheça bem o modelo de dados

Quando se trabalha com uma instrução SQL, como SELECT, INSERT, UPDATE e DELETE é extremamente importante tem um bom conhecimento do modelo de dados. De fato, o modelo pode impactar muito no desempenho da instrução, devido aos joins que são realizados, os filtros na cláusula where e outros fatores.

Já escrevi diversos artigos aqui no iMasters abordando questões de desempenho que tratam do modelo de dados: como eliminar tabelas desnecessárias, tipagem de dados correta e até a análise de modelos de dados do WordPress. Destaco também um artigo em inglês para o site SQLServerCentral.com, onde apresento algumas dicas para quem trabalha com modelos de dados grandes (com muitas tabelas e relacionamentos).

5. Quebre uma instrução SQL complexa em várias

Durante a minha carreira tenho encontrado muitos desenvolvedores com uma mania um tanto quanto esquisita: tentar montar relatórios utilizando uma instrução SELECT, por mais complexa que ela seja.

Ora, a instrução SELECT possui diversas cláusulas e opções que permitem realizar muitas operações de uma vez só, como filtros, ordenação, agregação, cálculos e outros. Porém, quanto mais operações uma única instrução SELECT realiza, mais complexa ela se torna. Aliás, recomendo o ótimo formatador online de instruções SQL, chamado SQL Online Formater, para auxiliar na melhora do visual de instruções SQL complexas e ajudar a compreendê-las. Este formatador está disponível em aqui.

Voltando ao assunto, a mania de fazer tudo em uma única instrução SELECT é considerada preciosa, e muitas vezes mais ajuda do que atrapalha. Faz muito sentido dividir as operações necessárias para se obter o relatório desejado em mais de uma instrução SELECT, pois assim fica mais fácil de dar manutenção no código, pode-se aplicar outras otimizações, gerenciar melhor o acesso a recursos (locks) e também fazer uso de opções de cache, criptografia e permissões do banco de dados. Uma dúvida pode surgir neste caso: como vou fazer minha aplicação/gerador de relatório utilizar mais de uma instrução SELECT para obter os dados que preciso?

Bem, neste caso existem algumas opções. A utilização de stored procedures é uma delas, mas pode ser utilizadas funções e views. Além das vantagens citadas também existem opções específicas de stored procedures e objetos programáveis do banco de dados que podem ser úteis, como criptografia, uso de parâmetros, opções de cache, entre outras.

6. Empregue os conceitos de teoria de conjuntos

Uma das técnicas de otimização mais disseminadas e, ouso a dizer, repetidas à exaustão, envolve trocar o processamento linha a linha (cursor) por operações baseadas em conjunto (set-based). Com certeza esta técnica é válida, mas não devemos parar por aí.

Atualmente, diversos dialetos do padrão SQL (Pl/SQL, T-SQL, etc) possuem operadores que são muito parecidos com as operações de conjuntos união, intersecção e diferença, como os operações UNION, INTERSECT e MINUS, respectivamente. Em muitas situações vale a pena pensar em termos de conjunto para montar uma instrução SQL otimizada. Por exemplo: para atualizar determinado conjunto de linhas, podemos pensar em obter todas as linhas desta tabela e retirar as linhas desta outra tabela. Neste caso deve-se considerar utilizar o operador MINUS.

O mais importante desta técnica não é, necessariamente, empregar este, ou aquele operador, ou joins; e sim mostrar que é possível pensar de maneira diferente em relação ao processo normal e muitas vezes já viciado na cabeça do desenvolvedor. A teoria de conjuntos, matematicamente falando, é muito poderosa e com alto grau de expressão. Saber aplicá-la quando se trabalha com instruções SQL pode fazer muita diferença, principalmente quando se busca obter desempenho.

7. Tenha casos de uso confiáveis para a instrução a ser otimizada

Quando se está modificando uma instrução SQL que já funciona corretamente, e se deseja melhorar seu desempenho, é praticamente obrigatório elaborar testes antes da modificação, pois assim é fácil determinar se a(s) modificação(es) implementada(s) quebraram, ou não a funcionalidade existente.

Por exemplo: suponha que uma instrução SELECT receba três parâmetros de filtro e, com certos valores A, B e C retorne, X linhas e T segundos. Guarde em algum lugar esta informação indicando que para os valores A, B e C dos respectivos parâmetros, estas X linhas são retornadas em T segundos. Este é um caso de testes simples e é conveniente armazenar outros valores para os três parâmetros, as linhas que eles retornam e o tempo de execução.

Depois que estas informações são armazenadas você já pode começar a otimizar a instrução SELECT. A cada nova técnica empregada verifica-se se houve um ganho de tempo de acordo com os valores dos parâmetros armazenados nos casos de teste e nas linhas retornadas.

Este procedimento pode parecer básico, mas isso é de extrema importância quando se está trabalhando com otimizações de instrução SQL e, infelizmente, poucas pessoas fazem isso de maneira pragmática e metódica no dia a dia.

8. Modifique ou exclua poucos dados por vez

Praticamente todos bancos de dados relacionais suportam o conceito de transações, sejam elas implícitas na instrução que modifica os dados (INSERT, UPDATE e DELETE), ou explícita pelo uso de comandos, como BEGIN TRANSACTION, ou similares . E para implementar este recurso há a necessidade de utilização de um log, que pode receber o nome de Transaction Log, Redo Log File, ou qualquer outro.

Utilizar log de transações gera uma implicação importante, que deve ser levada em consideração pelo desenvolvedor: o seu preenchimento. Geralmente, os bancos de dados possuem recursos manuais e automáticos para controlar como o log de transações é preenchido e limpo, porém fica a cargo do desenvolvedor saber que uma transação muito longa, ou seja, que afete muitas linhas, vai gerar um impacto significativo no log e também afetar o desempenho da instrução. Em poucas palavras: use transações curtas para se obter um bom desempenho, pois assim o log será preenchido de forma mais adequada e também serão minimizados os recursos de locks (ou qualquer outro mecanismo de controle de concorrência) necessários para a execução da instrução. Cabe ao desenvolvedor descobrir quando é pouco e quando é muito (em relação à quantidade de linhas por instrução) de acordo com o seu ambiente e modelo de dados.

Para ficar fácil de entender, basta imaginar a analogia do consumo do um bife. Você não vai querer comê-lo todo de uma vez (o que pode causar uma grande indigestão). É preciso cortá-lo em pedaços menores e abocanhá-los um por vez.

9. Cuidado com a recursividade

Trabalhar com recursividade em instruções SQL ainda é um desafio muito grande para diversos desenvolvedores. Apesar de já existirem soluções consolidadas, com muito tempo de mercado e até presentes no padrão SQL, não é raro encontrar instruções SQL não otimizadas para se trabalhar com recursividade. Além disso, ainda há a opção dos bancos NoSQL, que também permitem trabalhar com estruturas hierárquicas, em árvore, ou qualquer combinação entre elas de diversas maneiras.

De acordo com padrão SQL, existem um recurso chamado CTE (Common Table Expression), que permite manipular recursivamente partes de uma instrução SQL. Apesar de nem todos os bancos de dados implementarem este recursos em seus dialetos SQL, como o padrão sugere, ainda sim é possível fazer uso de CTEs em diversas situações. Do ponto de vista de entendimento prepare-se para encontrar instruções SELECT complexas e de difícil compreensão quando se emprega CTE. Do ponto de vista de desempenho, é muito fácil cair em uma recursão que realiza mais instruções do que uma solução interativa e, além disso, faz um uso excessivo da pilha interna que controla a recursividade.

Devido à estes fatores, deve-se utilizar com muita cautela soluções recursivas implementadas diretamente no SQL, principalmente pelo fato de já existirem diversos algoritmos e técnicas de manipulação de estruturas de dados otimizadas, testadas, conhecidas e estudadas para se realizar operações em estruturas hierárquicas.

10. Mantenha-se atualizado para aprender novas técnicas

Esta última técnica muitas vezes é menosprezada por profissionais mais experientes. Assim como o modelo de dados e as características do dado em si podem mudar a qualquer momento, os bancos de dados também evoluem (apesar do padrão SQL mais ou menos estacionado há algum tempo).

E isso quer dizer que as técnicas de otimização também devem evoluir. Algo que hoje é válido pode não ser mais depois de um curto período de tempo. Por exemplo, em certas versões de um banco de dado,s diversos livros, sites, blogs e vídeos indicavam que determinada técnica era melhor para otimizar o desempenho naquele momento. Mas com novas versões de bancos de dados, algumas destas técnicas não fazem mais sentido.

Por isso é importante ter sempre a consciência do contexto da técnica que está sendo aplicada. Muitas vezes o banco de dados é o mesmo, porém houve uma mudança na característica dos dados (seletividade, ordem, modelo, tipo de dados, etc) que tornaram certa otimização obsoleta e que não mais obtém o desempenho de outrora. Devido a isso, é sempre importante manter-se atualizado em relação não apenas ao que o mercado de banco de dados apresenta, mas também em relação ao ambiente na qual seus dados estão sendo manipulados.

Para finalizar, gostaria de fazer um pedido aos leitores: estou participando de um concurso que premiará as melhores histórias de otimização de desempenho. Bem, a minha entrada se chama “A day in a DBA Life” e os leitores que gostarem dela podem me ajudar clicando no botão “I Like this Story” nesta página (é preciso se logar no Facebook para votar).

Fonte: Mauro Pichiliani/IMaster

Tags | , , , , ,