@ Pierre 303 já disse isso, mas vou dizer novamente. DO utilizar índices em combinações de colunas. Um índice combinado (a, b)
é apenas um pouco mais lento para consultas do a
que um índice a
sozinho e é muito melhor se sua consulta combinar as duas colunas. Alguns bancos de dados podem ingressar em índices antes a
e b
depois da tabela, mas isso não é tão bom quanto ter um índice combinado. Ao criar um índice combinado, você deve colocar a coluna que provavelmente será pesquisada primeiro no índice combinado.
Se seu banco de dados suporta, DO colocar índices em funções que aparecem em consultas em vez de colunas. (Se você estiver chamando uma função em uma coluna, os índices nessa coluna serão inúteis.)
Se você estiver usando um banco de dados com os verdadeiros tabelas temporárias que você pode criar e destruir em tempo real (por exemplo, PostgreSQL, MySQL, mas não Oracle), então NÃO criar índices em tabelas temporárias.
Se você estiver usando um banco de dados que permite que ele (por exemplo, Oracle), DO bloqueio em boas planos de consulta. Os otimizadores de consulta ao longo do tempo alterarão os planos de consulta. Eles geralmente melhoram o plano. Mas às vezes eles pioram drasticamente. Você geralmente não notará melhorias no plano - a consulta não foi um gargalo. Mas um único plano ruim pode derrubar um site ocupado.
NÃO possui índices em tabelas nas quais você está prestes a fazer um grande carregamento de dados. É muito, muito mais rápido descartar índices, carregar os dados e reconstruir os índices do que mantê-los enquanto você carrega a tabela.
NÃO use índices em consultas que precisam acessar mais do que uma pequena fração de uma tabela grande. (Quão pequeno depende do hardware. 5% é uma regra prática decente.) Por exemplo, se você tiver dados com nomes e sexo, os nomes serão um bom candidato para indexação, pois qualquer nome representa uma pequena fração do total de linhas. Não seria útil indexar por sexo, pois você ainda precisará acessar 50% das linhas. Você realmente deseja usar uma verificação completa da tabela. O motivo é que os índices acabam acessando um arquivo grande aleatoriamente, fazendo com que você precise de pesquisas de disco. As buscas de disco são lentas. Como exemplo, recentemente consegui acelerar uma consulta de uma hora que parecia:
SELECT small_table.id, SUM(big_table.some_value)
FROM small_table
JOIN big_table
ON big_table.small_table_id = small_table.id
GROUP BY small_table.id
reescrevê-lo da seguinte maneira:
SELECT small_table.id, big_table_summary.summed_value
FROM small_table
JOIN (
SELECT small_table_id, SUM(some_value) as summed_value
FROM big_table
GROUP BY small_table_id
) big_table_summary
ON big_table_summary.small_table_id = small_table.id
o que forçou o banco de dados a entender que ele não deveria tentar usar o índice tentador big_table.small_table_id
. (Um bom banco de dados, como o Oracle, deve descobrir isso por conta própria. Esta consulta estava sendo executada no MySQL.)
Atualização: Aqui está uma explicação do ponto de busca de disco que eu fiz. Um índice fornece uma rápida pesquisa para dizer onde os dados estão na tabela. Isso geralmente é uma vitória, já que você analisará apenas os dados necessários. Mas nem sempre, principalmente se você finalmente analisar muitos dados. Os discos transmitem bem os dados, mas tornam as pesquisas lentas. Uma pesquisa aleatória nos dados do disco leva 1/200 de segundo. A versão lenta da consulta acabou fazendo algo como 600.000 deles e levou quase uma hora. (Ele fez mais pesquisas do que isso, mas o cache pegou algumas delas.) Por outro lado, a versão rápida sabia que precisava ler tudo e transmitir dados a algo como 70 MB / segundo. Ele conseguiu uma tabela de 11 GB em menos de 3 minutos.