Boas práticas de programação – SQL

Na correria do dia a dia, com prazos de entregas ao cliente cada vez menores, muitas vezes a qualidade do software é deixada de lado. Muitos dos comandos mais utilizados podem deteriorar o desempenho da aplicação, jogando no lixo a qualidade do software.

No banco de dados este tipo de problema também pode ocorrer, por isso este artigo trata de algumas dicas, ou boas práticas, para programação em SQL. É importante lembrar que praticamente todas as dicas são discutíveis em diferentes cenários, portanto, está aberto o debate.

Antes da batalha

Normalize o banco de dados. Isso quer dizer basicamente: divida tabelas grandes em tabelas menores e remova redundância de dados duplicados sem real necessidade.

Para obter maior desempenho utilize chaves primárias numéricas ou ainda campos pequenos nas chaves. Procure utilizar sempre as chaves primárias nas cláusulas WHERE

Use sempre o tipo de dados correto para armazenar os dados. Por exemplo, não armazene sexo, que vai ser M ou F em um campo VARCHAR, em vez disso use apenas 1 caractere: CHAR(1).

Utilize os mecanismos do banco de dados para persistência. Estruturas como PRIMARY KEY, FOREIGN KEY, etc. foram concebidos para isso.

Nunca utilizar

SELECT * FROM TABELA

Nunca se deve utilizar o comando SELECT * FROM TABELA. Quando o caractere coringa “*” é utilizado, o SGBD gastará um tempo de processamento para buscar quais são “todos os campos” da tabela especificada na cláusula FROM.

É evidente que em tempo de projeto este comando facilita a busca de informações e montagem de comandos mais complexos, porém na entrega da versão final do artefato de banco de dados o “*” deverá ser substituído pelos campos que realmente serão utilizados pela consulta.

SELECT ... FROM TABELA1, TABELA2

Quando uma tabela é colocada na cláusula FROM o SGBD criará um espaço em memória com uma réplica da tabela em questão. Colocar duas ou mais tabelas na cláusula FROM desperdiçará memória do SGBD. A melhor maneira de consultar dados em mais de uma tabela é utilizando JOINS.

O comando JOIN alocará memória apenas para os dados que atendam às condições especificadas na condição ON. Além disso, as variações de JOINS permitem uma flexibilidade muito maior de restrição de busca.

ORDER BY

Porque usar a memória do SGBD para ordenar um conjunto de dados que será enviado para a aplicação? Neste caso é melhor ordenar os dados na própria aplicação, liberando o SGBD para outros trabalhos.

CURSOR

Evite o uso de cursores. Eles consomem muito processamento pois têm que navegar individualmente em cada registro.

Evitar sempre que possível

COUNT(...)

Evite usar o comando COUNT para verificar se um registro esta presente na tabela. Utilizar o comando EXISTS fará o SGBD parar a consulta na primeira ocorrência, enquanto o COUNT percorrerá toda a tabela contando os resultados.

LIKE

O comando LIKE fará uma busca combinatória de strings. Dependendo da quantidade de registros na tabela pesquisada o desempenho do SGBD pode ruir.

Utilizar sempre

WHERE

Evite utilizar consultas sem a cláusula WHERE. Mesmo que absolutamente todos os registros devam ser retornados, atribua uma condição no WHERE que permita trazê-los.

Aperfeiçoar a clausula WHERE evitará buscas desnecessárias no SGBD. Simples exemplos são o uso de “>” e “>=”. Para retornar todas as pessoas de uma tabela com idade “> 3”, utilize no WHERE “>=4”. Dessa forma o SGBD não fará buscas de registros até encontrar o 4. Este princípio pode ser ainda melhor quando combinado com a criação de índices para o argumento utilizado na cláusula WHERE.

Stored Procedures e Functions

Utilizando-se stored procedures e functions ao invéz de escrever código no seu programa, vai garantir maior desempenho e segurança para seu sistema como um todo.

Transações

Utilize o conceito de transações. Vários problemas podem ocorer, por exemplo, a rede cair. Usar COMMITe ROLLBACK pode evitar muita dor de cabeça.

Quando possível deve-se criar instruções SQL idênticas, pois no momento da execução de uma instrução, o SGBD compila e preserva em memória. Na próxima execução, não vai precisar compilar novamente. Uma ótima técnica para fazer isso é utilizar variáveis nas suas instruções ao invés de passar parâmetros para o SGBD.

LOCK

Quando possível, trave (lock) uma tabela para executar alguma operação que vai demandar muito acesso concorrente. Por exemplo, alterar a estrutura de uma tabela grande ou importar dados nesta tabela.

Considerações sobre índices

Não deve ser criados índices em campos que são alterados constantemente, pois o SGBD vai ter que atualizar toda sua estrutura de índices em qualquer UPDATE feito no campo.

Na maioria dos SGBDs, chaves primárias e estrangeiras já são indexadas na criação. Sempre que possível utilize estes campos nas pesquisas.

Não é necessário criar muitos índices no SGBD. Utilize sempre que uma ação possa ser aperfeiçoada. O SGBS cria uma estrutura para gerenciamento de índices que também consomem processamento para sua manutenção.

Ao fazer backup dos dados não é necessário importar ou exportar índices. Recriar os índices consome menos processamento que a sua importação.

Não deve ser criado índices para campos que possuem pouca ou nenhuma interação com cláusulas WHERE.

Entender os fundamentos de banco de dados é o pricípio de tudo. Segue sugestões de leitura para aperfeiçoamento: “Sistema de Banco de Dados”, de Abraham Silberschatz, Henry F. Korth e S. Sudarshan lançado no Brasil pela Editora Elsevier; “Sistemas de Banco de Dados”, de Elmasri e Navathe