Sei sulla pagina 1di 3

Cartilha de boas prticas de SQL

1. Normalize seu banco de dados. Isso quer dizer basicamente, divida tabelas grandes em tabelas menores e remova redundncia, ou seja, que dados estejam duplicados sem real necessidade. Se tiver que desnormalizar alguma tabela pense na ocupao e no rendimento antes de proceder. 2. Em instrues Select, evite usar *. Seja restritivo, traga somente os campos realmente necessrios, isso alivia a memria do servidor, diminui trfego na rede, etc. Algumas pessoas defendem que tambm no devem ser criados determinados campos, por exemplo, voc tem A + B e pretende guardar C onde C = A + B. Ao invs de criar uma coluna para armazenar C, passe a utilizar select (A+B) AS C from tabela. Esse pensamento pode no ser necessariamente vlido para Dws. 3. Para obter maior performance, utilize chaves primrias numricas, de preferencia campos do tipo serial. 4. Utilizar stored procedures e functions ao invs de escrever cdigo no seu programa, vai garantir maior desempenho e segurana para seu sistema como um todo. 5. Utilize o conceito de transaes. Vrios problemas podem ocorer, por exemplo, a rede cair. Aprenda sobre commit e rollback. 6. Use sempre o tipo de dado correto para armazenar os dados. Por exemplo, no armazene sexo, que vai ser M ou F, em um campo Varchar, use apenas 1 caractere: CHAR(1). 7. Evite o uso de cursores, eles consomem muito tempo j que navegam registro por registro. 8. Otimize a clausula WHERE: Simples exemplo o uso de > e >=. Se voc quer retornar todas as pessoas de uma tabela que tem idade > 3, use no where >= 4, pois na primeira forma, se houver muitas linhas com idade = 3, o engine do banco de dados far scan de muitas pginas at encontrar idade > 3. Esse princpio vlido desde que voc tenha um ndice na idade. 9. Utilize os mecanismos do banco de dados para persistncia: Primary Key, Foreign Key, etc so feitos e otimizados para isso. 10. Sempre utilize o nome das colunas em instrues SELECT, INSERT, UPDATE evitando utilizar *. 11. Evite utilizar o operador LIKE, ele pode facilmente fazer o desempenho de um banco de dados ruir! 12. Utilize EXISTS ao invs de COUNT para verificar se existe um determinado registro em uma

tabela. comum ver desenvolvedores fazendo um select count(X) from Y para verificar se o COUNT maior que 0. Utilizando-se EXISTS, o SGBD vai parar no primeiro registro encontrado, se utilizar count, o banco vai varrer toda a tabela. 13- Em joins de tipos de dados diferentes, o SGBD vai ter que converter o tipo hierarquicamente inferior para o outro tipo a fim de efetuar a comparao, e assim, no vai utilizar um ndice caso exista. 14. Sobre ndices: No crie ndices em campos que so alterados constantemente, pois o banco vai ter que atualizar toda sua estrutura de ndices em qualquer update feito no campo. Prefira criar os ndices em chaves primrias e estrangeiras, e em suas queries, utilize estes ndices. No tenha muitos ndices em seu banco, s o necessrio: uma breve explicao sobre o motivo disso, que o banco de dados mantem toda uma estrutura para gerenciar os ndices, ento, quanto mais ndices, mais tempo/processamento o SGBD vai utilizar para a manuteno dos mesmos. No crie ndices em colunas que possuem pouca variao de valores. 15. Uma instruo que consome um maior processamento a instruo IN, que utilizada quando necessrio fazer o filtro de um vetor de dados. O exemplo abaixo informa todos os clientes que possuem algum telefone. SELECT nome FROM cliente WHERE id IN (SELECT clienteId FROM telefone) Outra maneira de informar estes registros seria utilizar (novamente) a instruo EXISTS ao invs da instruo IN. SELECT cliente.nome FROM cliente WHERE EXISTS (SELECT telefone.clienteId FROM telefone WHERE telefone.clienteId = cliente.id) A instruo EXISTS uma instruo extremamente rpida porque utiliza pouco recurso de hardware. como se retornasse uma varivel booleana. 16. OR x UNION O banco de dados no consegue otimizar clusulas de join ligadas por OR. Neste caso mais eficiente ligar os conjuntos de resultados por UNION. Por exemplo: SELECT a FROM tab1,tab2 WHERE tab1.a = tab2.a OR tab1.x = tab2.x pode ser reescrito como : SELECT a FROM tab1, tab2 WHERE tab1.a = tab2.a UNION

SELECT a FROM tab1, tab2 WHERE tab1.x = tab2.x A diferena que na segunda forma, so eliminadas as linhas duplicadas, o que pode ser contornado com UNION ALL. 17. Sempre que possvel faa uso do Explain Plan. O comando EXPLAIN mostra o plano de execuo que o planejador do PostgreSQL gera para o comando fornecido. O plano de execuo mostra como as tabelas referenciadas pelo comando so varridas por uma varredura seqencial simples, varredura pelo ndice, etc. e, se vrias tabelas forem referenciadas, quais algoritmos de juno so utilizados para unir as linhas das tabelas de entrada. Caso seja indicado na consulta Table Access (Full), isso indica que na tabela est ocorrendo leitura sem a utilizao de ndices. Desta forma, a consulta fica pesada, dependendo das quantidades de registros que contm na mesma, aumentando o tempo de retorno. A dica : Quando temos um plano de acesso de uma query com esta situao, devemos observar a quantidade de itens que a tabela possui. interessante criar um ndice para tabelas com mais de 2000 registros. Ex.: Mostrar o plano para uma consulta simples em uma tabela com uma nica coluna integer e 10.000 linhas: EXPLAIN SELECT * FROM foo; QUERY PLAN --------------------------------------------------------Seq Scan on foo (cost=0.00..155.00 rows=10000 width=4) (1 linha) A opo ANALYZE faz o comando ser realmente executado, e no apenas planejado. O tempo total decorrido gasto em cada n do plano (em milissegundos) e o nmero total de linhas realmente retornadas so adicionados ao que mostrado. Esta opo til para ver se as estimativas do planejador esto prximas da realidade. Ex.: EXPLAIN ANALYZE SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50 AND t1.unique2 = t2.unique2; QUERY PLAN ------------------------------------------------------------------------------Nested Loop (cost=0.00..327.02 rows=49 width=296) (actual time=1.181..29.822 rows=50 loops=1) -> Index Scan using tenk1_unique1 on tenk1 t1 (cost=0.00..179.33 rows=49 width=148) (actual time=0.630..8.917 rows=50 loops=1) Index Cond: (unique1 < 50) -> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..3.01 rows=1 width=148) (actual time=0.295..0.324 rows=1 loops=50) Index Cond: ("outer".unique2 = t2.unique2) Total runtime: 31.604 ms

Potrebbero piacerti anche