Práticas recomendadas para seguir com índices de banco de dados [fechado]

17

Quais são alguns DOs e DONTs para melhorar o desempenho do banco de dados usando o índice?

Um DO seria um caso em que um índice deveria ser criado ou outra dica relacionada a índices que melhoraria o desempenho.

Um DONT será um caso em que um índice não deve ser criado ou outra ação relacionada ao índice que possa prejudicar o desempenho.

Click Voto a favor
fonte
3
perfil, perfil, perfil
GrandmasterB

Respostas:

15

Isso depende em parte do uso do banco de dados, uma vez que, em geral, os índices desaceleram inserções e atualizações e aceleram as consultas. Em um armazém de dados, geralmente não há atualizações e inserções em lote, facilitando a criação de índices, e muitas e muitas consultas, que são aceleradas com muitos índices. Em um banco de dados on-line para vendas na Web e similares, há muitas inserções e atualizações; portanto, ter mais do que alguns índices cuidadosamente selecionados diminui a velocidade.

Se você receber muitas consultas de um tipo específico, poderá criar um índice para a consulta, embora isso seja mais para processamento on-line do que para data warehouses. Se determinadas colunas aparecerem muito em consultas, convém um índice nessa coluna, e isso é especialmente útil para data warehouses, que são consultados de várias maneiras diferentes e geralmente imprevisíveis.

Sempre que você adicionar ou remover um índice, tente fazer um teste de desempenho para ver qual efeito ele tem. Sem isso, você está atirando às cegas.

Existem livros sobre o ajuste de consultas e bancos de dados, geralmente específicos para um sistema de banco de dados e o uso das ferramentas desse RDBMS. Porém, se você precisar otimizar muito o banco de dados, estará executando uma operação grande e provavelmente deverá contratar um DBA com o conhecimento adequado.

David Thornley
fonte
17

Depende muito de como você usa suas tabelas. Não existe uma resposta única e simples.

O melhor conselho que posso dar é: use consultores de ajuste . Eles analisarão os comandos do banco de dados enquanto você estiver usando o aplicativo e, em seguida, executarão testes de carga contra ele para fornecer conselhos significativos.

Eles existem para SQL Server e Oracle . Não sei se outros DBMS os possuem, mas duvido que não forneçam essas ferramentas básicas.

Poucas recomendações aleatórias:

  • Os índices fornecem ganhos de alto desempenho quando aplicados em colunas frequentemente incluídas na cláusula WHERE
  • Use o índice clusterizado para a coluna mais usada em suas consultas.
  • Não esqueça que você pode criar vários índices com a combinação de colunas (como eles são usados ​​em suas consultas)
  • Ter muitos índices diminuirá o desempenho dos comandos INSERT.

Último conselho : se o desempenho do DB for realmente importante para o seu projeto, contrate um especialista. Foi o que eu fiz.


fonte
2
+1 para índices em combinações de colunas. Indexa colunas ae nãob é o mesmo que um índice ativado . O último é quase tão bom quanto o índice ativado para acelerar consultas com uma condição ativada, é massivamente melhor para consultas com condições ativadas e , e não é útil apenas para consultas ativadas. (A maioria dos bancos de dados não vai usá-lo a Oracle, mas não recebe a milhagem fora dele que ele regularmente faz..)(a, b)aaabb
btilly
2
+1, acrescentaria "aprender a ler planos de consulta para que você saiba o que index"
Steven A. Lowe
4

@ 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 aque um índice asozinho e é muito melhor se sua consulta combinar as duas colunas. Alguns bancos de dados podem ingressar em índices antes ae bdepois 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.

btilly
fonte
Olá, estou confuso com o seu exemplo. Eu pensaria que o uso do índice tornaria as coisas mais rápidas, não é esse o objetivo dos índices? Você está dizendo que, se uma consulta acessar> 5% de uma tabela, ter um índice na coluna que você está pesquisando tornaria as coisas mais lentas?
Click Voto a favor
@Click Upvote: se uma consulta acessar mais de 5% (fração exata altamente dependente de hardware e dados) de uma tabela, é mais rápido não usar um índice para essa consulta. Ter um índice não dói, desde que você não o use. Vou atualizar com mais detalhes sobre o porquê disso.
btilly
Informação útil. Mais sobre isso, por exemplo, mysqlperformanceblog.com/2007/08/28/… Mas eu queria saber, 'ignorar chave' não era o ideal para você fazer uma subconsulta?
Inca
@ Inca: Eu não estava ciente de 'ignorar chave'. Alterno os bancos de dados o suficiente para que muitas vezes haja coisas específicas do banco de dados das quais não estou ciente. Pelos sons que funcionariam, mas significativamente menos eficientemente do que minha solução final. A diferença é que isso se juntaria ao grupo, enquanto o meu agrupava e depois ao grupo. Isso economiza trabalho na associação porque menos registros precisam ser associados.
btilly 25/05
"Um bom banco de dados (por exemplo, Oracle, mas não MySQL)": evite coisas promocionais estúpidas como essa, especialmente quando você ignora o fato de que o MySQL pode perfeitamente usar vários índices ao mesmo tempo (anotado "INDEX MERGE" nos planos de consulta) .
Patrick Allaert
2

DO: indexe os poucos campos que você mais acessa por meio de consulta e / ou comparação.

NÃO: indexe todos os campos da tabela pensando que será mais rápido.

Não tenho estatísticas, mas tento manter no máximo 4 campos indexados em uma tabela, se posso ajudá-lo. Normalizar meus bancos de dados geralmente ajuda a manter esses números baixos, pois tudo se torna pesquisável por chave numérica (que é mais rápida de qualquer maneira). Eu tento ficar longe dos campos de texto completo para indexação. Eles são bem pesados.

Joel Etherton
fonte
2

Basicamente, os índices aceleram a pesquisa, mas diminuem a velocidade da escrita e ocupam espaço. Essa é a troca que está sendo feita.

Qualquer campo que é freqüentemente usado para ingressar, pesquisar / comparar ou fazer pedidos por é candidato a um índice. Saber que é realmente benéfico, meça. No entanto, as chaves estrangeiras de tabelas fortemente unidas com lotes (> 1000s) de registros e poucas inserções serão recompensadas.

Para campos de texto, você pode indexar em uma parte do campo (por exemplo, os 6 primeiros caracteres), o que aceleraria sua consulta, mas diminuiria a carga nos índices. A pesquisa de texto completo (pesquisa like %substring%) requer técnicas diferentes, com as quais eu não estou familiarizado, por isso não posso aconselhá-lo.

Uma situação importante em que os índices não ajudam: você não pode usar o índice de campos completos de data ou data e hora quando pesquisar (/ ingressar / fazer pedido) em parte da data. Um índice date_createdativado não o ajudará com uma consulta como select * from t where year(date_created) = 2011. No mysql, você não pode criar um índice em parte da data. (Quando você usa ' between' em vez de year()usar o índice no campo de data.)

Mais informações sobre o MYSQL no manual: http://dev.mysql.com/doc/refman/5.6/en/optimization-indexes.html

Inca
fonte
1

FAÇA: Tente manter o tamanho total do índice em cluster no mínimo. As entradas de índice em cluster serão incluídas em outros índices não em cluster e a partir daqui vem o potencial de desperdiçar espaço em disco.


fonte
1

Pense em uma tabela como um léxico, onde os artigos são classificados por ordem de aparência (ou nenhuma ordem útil) e em um índice de tabela como um índice de livros para esse léxico.

Você usa um índice para encontrar rapidamente algo em um livro. Em vez de digitalizar o livro inteiro, você só precisa encontrar a chave no índice (um índice geralmente sendo classificado de alguma forma (por categoria, campo científico, época histórica etc.), isso também significa que você não precisará digitalizar todo o índice) e, em seguida, pule para a página direita.

Ao contrário de um livro, no entanto, uma tabela não é impressa uma vez e depois imutável. Ele é atualizado o tempo todo e, portanto, todo índice deve ser atualizado com ele. Obviamente, isso tem um custo de espaço e tempo, que só pode ser justificado pela utilidade de um índice.

Portanto, use um índice para uma coluna, se essa coluna for usada como chave em consultas de pesquisa frequentes e não use uma, se não for. A palavra frequente é um quantificador tão bom quanto possível, quando se fala em geral. No final, você terá que fazer uma boa estimativa de quais são frequentes e, em seguida, simplesmente comparar o desempenho com ou sem índice em caso de dúvida.

back2dos
fonte