Estou trabalhando em um projeto com um banco de dados Oracle bastante grande (embora minha pergunta se aplique igualmente a outros bancos de dados). Temos uma interface da web que permite aos usuários pesquisar em quase todas as combinações possíveis de campos.
Para tornar essas pesquisas mais rápidas, estamos adicionando índices aos campos e combinações de campos nos quais acreditamos que os usuários irão pesquisar normalmente. No entanto, como não sabemos realmente como nossos clientes usarão este software, é difícil dizer quais índices criar.
O espaço não é uma preocupação; temos uma unidade RAID de 4 terabytes, da qual usamos apenas uma pequena fração. No entanto, estou preocupado com as possíveis penalidades de desempenho por ter muitos índices. Como esses índices precisam ser atualizados sempre que uma linha é adicionada, excluída ou modificada, imagino que não seria uma boa ideia ter dezenas de índices em uma única tabela.
Então, quantos índices são considerados muitos? 10? 25? 50? Ou devo apenas cobrir os casos realmente, realmente comuns e óbvios e ignorar todo o resto?
fonte
Eu geralmente procuro assim.
Como acontece com qualquer otimização, eu paro quando o desempenho solicitado é alcançado (isso obviamente implica que o ponto 0. estaria recebendo requisitos de desempenho específicos).
fonte
Todo mundo tem lhe dado ótimos conselhos. Tenho uma sugestão adicional para você conforme você avança. Em algum momento, você deve tomar uma decisão quanto à sua melhor estratégia de indexação. No final das contas, a melhor estratégia de indexação PLANNED ainda pode acabar criando índices que acabam não sendo usados. Uma estratégia que permite localizar índices que não são usados é monitorar o uso do índice. Você faz isso da seguinte maneira: -
Você pode então monitorar se o índice é usado ou não daquele ponto em diante, consultando v $ object_usage. Informações sobre isso podem ser encontradas no Oracle® Database Administrator's Guide .
Lembre-se de que, se você tiver uma estratégia de armazenamento de eliminar índices antes de atualizar uma tabela e, em seguida, recriá-los, terá que configurar o índice para monitoramento novamente e perderá todo o histórico de monitoramento desse índice.
fonte
No armazenamento de dados, é muito comum ter um grande número de índices. Trabalhei com tabelas de fatos com duzentas colunas e 190 delas indexadas.
Embora haja uma sobrecarga para isso, deve ser entendido no contexto que em um data warehouse, geralmente inserimos uma linha apenas uma vez, nunca a atualizamos, mas ela pode participar de milhares de consultas SELECT que podem se beneficiar da indexação em qualquer um dos as colunas.
Para flexibilidade máxima, um data warehouse geralmente usa índices de bitmap de coluna única, exceto em colunas de alta cardinalidade, onde índices btree (compactados) podem ser usados.
A sobrecarga na manutenção do índice está principalmente associada à despesa de gravação em muitos blocos e a divisão do bloco à medida que novas linhas são adicionadas com valores que estão "no meio" dos intervalos de valores existentes para essa coluna. Isso pode ser atenuado pelo particionamento e tendo as novas cargas de dados alinhadas com o esquema de particionamento e usando inserções de caminho direto.
Para abordar sua questão mais diretamente, acho que provavelmente não há problema em indexar o óbvio no início, mas não tenha medo de adicionar mais índices se as consultas na tabela forem se beneficiar.
fonte
Em uma paráfrase de Einstein sobre simplicidade, adicione quantos índices precisar e nada mais.
Sério, entretanto, cada índice que você adiciona requer manutenção sempre que os dados são adicionados à tabela. Em tabelas que são principalmente somente leitura, muitos índices são uma coisa boa. Em mesas altamente dinâmicas, quanto menos, melhor.
Meu conselho é cobrir os casos comuns e óbvios e, então, conforme você encontrar problemas em que precisa de mais velocidade para obter dados de tabelas específicas, avalie e adicione índices nesse ponto.
Além disso, é uma boa ideia reavaliar seus esquemas de indexação a cada poucos meses, apenas para ver se há algo novo que precisa de indexação ou algum índice que você criou que não está sendo usado para nada e deve ser eliminado .
fonte
Além dos pontos que todos levantaram, o Cost Based Optimizer incorre em um custo ao criar um plano para uma instrução SQL se houver mais índices porque há mais combinações a serem consideradas. Você pode reduzir isso usando variáveis de ligação corretamente para que as instruções SQL permaneçam no cache SQL. O Oracle pode então fazer uma análise suave e reutilizar o plano que encontrou da última vez.
Como sempre, nada é simples. Se houver colunas distorcidas e histogramas envolvidos, isso pode ser uma má ideia.
Em nossos aplicativos da web, tendemos a limitar as combinações de pesquisas que permitimos. Caso contrário, você teria que testar literalmente todas as combinações de desempenho para garantir que não tivesse um problema oculto que alguém encontrasse um dia. Também implementamos limites de recursos para impedir que isso cause problemas em outras partes do aplicativo, caso algo dê errado.
fonte
Fiz alguns testes simples no meu projeto real e no banco de dados MySql real. Já respondi neste tópico: Qual é o custo de indexar várias colunas db?
Mas acho que será melhor se eu citar aqui:
fonte
Em última análise, quantos índices você precisa dependem do comportamento de seus aplicativos que funcionam no servidor de banco de dados.
Em geral, quanto mais você insere, mais dolorosos se tornam seus índices. Cada vez que você faz uma inserção, todos os índices que incluem aquela tabela devem ser atualizados.
Agora, se o seu aplicativo tiver uma quantidade decente de leitura, ou ainda mais se for quase toda leitura, os índices são o caminho a seguir, pois haverá grandes melhorias de desempenho por um custo muito baixo.
fonte
Não há uma resposta estática na minha opinião, esse tipo de coisa se enquadra no 'ajuste de desempenho'.
Pode ser que tudo o que o seu aplicativo faz seja pesquisado por uma chave primária, ou pode ser o contrário, pois as consultas são feitas sobre combinações de campos não restritas e qualquer um em particular pode ser usado a qualquer momento.
Além de apenas indexar, há a reogranização de seu banco de dados para incluir campos de pesquisa calculados, tabelas de divisão, etc - é realmente dependente de seus formatos de carga e parâmetros de consulta, quanto / quais dados "realmente" precisam ser recuperados por uma consulta.
Se todo o seu banco de dados é fronteado por fachadas de procedimento armazenado, a rotação se torna um pouco mais fácil, pois você não precisa se preocupar com cada consulta ad-hoc. Ou você pode ter uma compreensão profunda do tipo de consultas que atingirão seu banco de dados e pode limitar o ajuste a elas.
Para o SQL Server, achei o Orientador de Otimização do Mecanismo de Banco de Dados útil - você configura cargas de trabalho 'típicas' e ele pode fazer recomendações sobre como adicionar / remover índices e estatísticas. Tenho certeza de que outros bancos de dados possuem ferramentas semelhantes, sejam "oficiais" ou de terceiros.
fonte
Esta é realmente uma questão mais teórica do que prática. O impacto dos índices no seu desempenho depende do hardware que você possui, da versão do Oracle, dos tipos de índice, etc. Ontem ouvi que a Oracle anunciou um armazenamento dedicado, feito pela HP, que deve funcionar 10 vezes mais rápido com o banco de dados 11g. Quanto ao seu caso, podem haver várias soluções: 1. Ter uma grande quantidade de índices (> 20) e reconstruí-los diariamente (noturno). Isso seria especialmente útil se a tabela obtiver milhares de atualizações / exclusões diariamente. 2. Particione sua tabela (se isso se aplicar ao seu modelo de dados). 3. Use uma tabela separada para dados novos / atualizados e execute um processo noturno que combina os dados. Isso exigiria uma mudança na lógica do aplicativo. 4. Mude para IOT (tabela organizada de índice), se seus dados suportarem isso.
É claro que pode haver muito mais soluções para esse caso. Minha primeira sugestão para você, seria clonar o banco de dados para um ambiente de desenvolvimento e executar alguns testes de estresse contra ele.
fonte
Se você faz mais leituras (e poucas atualizações), não há realmente nenhuma razão para não indexar tudo que você precisa indexar. Se você atualiza com frequência, deve ter cuidado com a quantidade de índices que possui. Não existe um número difícil, mas você notará quando as coisas começarem a desacelerar. Certifique-se de que seu índice clusterizado seja o que faz mais sentido com base nos dados.
fonte
Uma coisa que você pode considerar é construir índices para direcionar uma combinação padrão de pesquisas. Se a coluna1 for comumente pesquisada e a coluna2 for frequentemente usada com ela e a coluna3 às vezes for usada com a coluna2 e coluna1, então um índice na coluna1, coluna2 e coluna3 nessa ordem pode ser usado para qualquer uma dessas três circunstâncias, embora seja apenas um índice que deve ser mantido.
fonte
Um índice impõe um custo quando a tabela subjacente é atualizada. Um índice fornece um benefício quando é usado para acelerar uma consulta. Para cada índice, você precisa equilibrar o custo em relação ao benefício. Quanto mais lenta a consulta é executada sem o índice? Quanto de um benefício está funcionando mais rápido? Você ou seus usuários podem tolerar a velocidade lenta quando o índice está ausente?
Você pode tolerar o tempo adicional necessário para concluir uma atualização?
Você precisa comparar custos e benefícios. Isso é particular para sua situação. Não existe um número mágico de índices que ultrapasse o limite de "muitos".
Também há o custo do espaço necessário para armazenar o índice, mas você disse que na sua situação isso não é um problema. O mesmo é verdade na maioria das situações, dado o quão barato o espaço em disco se tornou.
fonte
Quantas colunas existem? Sempre me disseram para criar índices de coluna única, não índices de várias colunas. Portanto, não há mais índices do que a quantidade de colunas, IMHO.
fonte
O que realmente importa é não adicionar um índice a menos que você saiba (e isso geralmente significa reunir estatísticas de uso) que ele será usado com muito mais frequência do que atualizado.
Qualquer índice que não atenda a esses critérios custará mais para reconstruir do que a penalidade de desempenho de não tê-lo no caso estranho de ser usado.
fonte
O servidor SQL oferece algumas boas ferramentas que permitem ver quais índices estão realmente sendo usados. Este artigo, http://www.mssqltips.com/tip.asp?tip=1239 , fornece algumas consultas que permitem obter uma visão melhor de quanto um índice é usado, em oposição ao quanto é atualizado.
fonte
É totalmente baseado nas colunas que estão sendo usadas na cláusula Where. E como o polegar da regra, devemos ter índices em colunas de chave estrangeira para evitar DEADLOCKS. O relatório AWR deve ser analisado periodicamente para entender a necessidade de índices.
fonte