Indexação desde o início ou quando surgir um problema de desempenho?


15

Minha pergunta é sobre o uso de índices.

  1. Devo começar a indexar desde o início ou quando surgir um problema de desempenho?

  2. Também podemos criar um índice temporário durante a execução de uma consulta. Quais são os prós e os contras de tais técnicas?

Respostas:


17

Devo começar a indexar desde o início ou quando surgir um problema de desempenho?

A estratégia de indexação tende a evoluir à medida que surgem os padrões de uso. Dito isto, também existem estratégias e diretrizes de design que podem ser aplicadas antecipadamente.

  • Escolha uma boa chave de cluster . Geralmente, você pode determinar o índice clusterizado apropriado no tempo de design, com base no padrão esperado de inserções em uma tabela. Se um caso convincente surgir para uma mudança no futuro, que assim seja.

  • Crie suas restrições principais e outras exclusivas . Eles serão aplicados por índices exclusivos.

  • Crie suas chaves estrangeiras e índices não agrupados associados . Chaves estrangeiras são as colunas de junção referenciadas com mais frequência, portanto, indexe-as desde o início.

  • Crie índices para qualquer consulta obviamente altamente seletiva . Para padrões de consulta que você já sabe, serão altamente seletivos e provavelmente usarão pesquisas em vez de varreduras.

Além do exposto, adote uma abordagem gradual e holística para implementar novos índices. Por holística, quero dizer avaliar o potencial benefício e impacto de todas as consultas e índices existentes ao avaliar uma adição.

Um problema não incomum nos círculos do SQL Server é a superindexação, como resultado das orientações das dicas de DMVs e SSMS do índice ausentes. Nenhuma dessas ferramentas avalia índices existentes e sugere alegremente que você crie um novo índice de 6 colunas em vez de adicionar uma única coluna a um índice de 5 colunas existente.

-- If you have this
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
)

-- But your query would benefit from the addition of a column
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

-- SSMS will suggest you create this instead
CREATE NONCLUSTERED INDEX [IX_MyTable_AnotherIndexWithTheSameColumnsAsTheExistingIndexPlusCol6] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

Kimberly Tripp tem um excelente material sobre estratégia de indexação que, enquanto o foco no SQL é aplicável a outras plataformas. Para o pessoal do SQL Server, existem algumas ferramentas úteis para identificar duplicatas, como no exemplo acima.

Também podemos criar um índice temporário durante a execução de uma consulta. Quais são os prós e os contras de tais técnicas?

Isso geralmente se aplica apenas a consultas raramente executadas, geralmente ETL. Você precisa avaliar:

  1. O tempo gasto para criar o índice reduz o tempo de execução da consulta.
  2. A sobrecarga de manutenção de deixar o índice no lugar supera o tempo necessário para criar / descartar quando necessário.

3
Chave de cluster de +1, Chave estrangeira, Chave única / primária e não confiando em DMVs de índice ausentes pelo valor nominal ... Todas essas coisas são ótimos conselhos. Lidar com índices existentes, no SQL Server, é muito fácil de monitorar usando a DMV sys.dm_db_index_usage_stats. Durante um período de tempo, você pode listar índices que não foram verificados ou consultados, além de verificar que esses mesmos índices foram atualizados várias vezes. Isso é indicativo de superindexação.
Matt M

11
+1, no entanto, 'crie índices para quaisquer consultas obviamente altamente seletivas'. não cobre todos os outros cenários. Os índices podem ajudar a classificar os resultados, mesmo que suas consultas não sejam altamente seletivas. Eles também podem acelerar as consultas se cobrirem todas as colunas selecionadas.
razoável,

11
Concordou, mas a questão estava procurando um ponto de partida e não o fim do jogo. A identificação de consultas a cobrir é difícil sem padrões de uso, pois raramente é possível cobrir todas elas.
Mark-Storey-Smith

8

Há realmente riscos associados a ambas as abordagens:

Opção a) Índice desde o início, mas não percebe que você criou vários índices que nunca são usados. Isso adiciona um pouco de sobrecarga (principalmente às consultas que modificam dados, mas também com a otimização das instruções SELECT tentando identificar o melhor índice).

Você precisará se disciplinar para identificar os índices que não estão mais sendo usados ​​e tentar removê-los (o PostgreSQL pode fazer isso; infelizmente o MySQL, por comparação, é muito fraco nesse processo).

Opção b) Não adicione índices até que as pessoas comecem a reclamar, ou suas ferramentas de diagnóstico acionam que determinadas consultas são lentas e podem ser melhoradas.

O risco que você introduz é que você não tem uma janela de tempo grande o suficiente entre o momento em que percebe que precisa do índice e quando precisa adicioná-lo.

O PostgreSQL suporta a criação de índices CONCURRENTLY, o que reduz um pouco do estresse desse requisito de adição repentina de índice, mas há algumas ressalvas observadas no manual.


A opção (b) tende a ser a minha preferência, mas acho que um híbrido de ambas as opções é provavelmente a melhor solução. Tem a ver com o seu nível de confiança sobre se você acha que um índice será realmente usado.

O que torna essa discussão particularmente complexa é que geralmente é fácil alterar índices, mas é mais difícil alterar o esquema. Não quero promover a reação tardia de b como desculpa para ser imprudente.


4

Além da resposta de Mark

Você pode ter uma ideia realizando dados de teste realistas nas quantidades esperadas. Eu já vi muitos casos (muitos) em que uma consulta é executada com 1000 linhas, mas não o milhão em produção.

Se puder, trabalhe em uma cópia da produção posteriormente,

Obviamente, vi o problema estranho apenas na produção por causa dos padrões de uso quando tudo o resto é idêntico

Índices temporários? Fora dos padrões de carregamento ETL, se você precisar deles uma vez, precisará deles novamente. Não se esqueça: um índice criar / soltar é uma gravação e é registrado = mais carregamento


3

Apenas para adicionar algumas coisas.

  • Índices temporários são uma péssima idéia ... a menos que o índice esteja em uma tabela temporária.
  • Os índices ocupam muito mais espaço de dados (assim como outras despesas gerais) do que as pessoas imaginam. Portanto, crie-os de forma conservadora.

Esta é a minha abordagem.

  1. Semelhante ao Mark, crie índices onde eles fizerem sentido, mas não o atrasem.
  2. Você não precisa esperar até o desempenho diminuir para criar novos índices. Sempre que você escrever um novo SQL, execute um plano de consulta (de preferência no seu banco de dados prod). Você deve poder ver se é necessário um novo índice.
  3. Não tenha medo de colocar > 0ou > ""em suas cláusulas where para colunas não utilizadas.

    1. Ou seja, digamos que você tenha um índice em A, B, C e D. No entanto, você só possui informações A, B, D. Não há razão para que você não possa fazer-
    select * from blah 
    where A="one" 
    and B="two" 
    and C>=""     --to match index
    and D="four"
    
    --This will use your existing index. No need to create a redundant one.

Outra coisa, isso está no fórum "dba", mas a criação do índice deve ser realmente de responsabilidade do desenvolvedor, não do dba. (Nos casos em que eles são completamente separados.) #
User606723 17/10

2
Sua afirmação sobre o espaço ocupado pelos índices é um pouco enganadora, há muito pouca sobrecarga em um índice não agrupado. Se você pudesse postar uma pergunta sobre esse ponto, valeria a pena explorar mais. Em segundo lugar, discordo que a criação de índice é o domínio do desenvolvedor. É uma das áreas em que a colaboração entre desenvolvedor e DBA pode gerar os melhores resultados.
Mark-Storey-Smith

11
Vou dar um exemplo de uma de nossas tabelas. tamanho da tabela: 21052404 KB. Tamanho de um índice não agrupado nesta tabela: 6637470 KB. Muito pouca sobrecarga? Eu acho que não. Além disso, não estou dizendo que os DBAs não devem ser colaborados, estou dizendo que deve ser responsabilidade do desenvolvedor determinar se um novo índice precisa ser criado. Eles não devem escrever SQL e esperar que o dbas descubra isso por conta própria.
user606723

11
Você não pode citar números como esse sem contexto. Sem especificar as colunas do índice NC e a chave em cluster, é impossível calcular a proporção de custos indiretos versus dados.
Mark Storey-Smith

Toque. A tecla é um [numérico (24), caractere, data] e as colunas NC são [data, numérico (24)]. (Apenas duas colunas neste índice em particular).
user606723

2

Vou tentar responder apenas a primeira pergunta. Se você puder estimar, aproximadamente desde o início, quantos registros você terá em suas tabelas após um certo período de tempo, então eu diria que é melhor começar do início para criar alguns índices. Tente usar algumas ferramentas de teste ou scripts de teste que automatizarão o maior número possível de chamadas para as chamadas de aplicativo que você acha que serão usadas com mais frequência e verá quais verificações de tabela podem ser evitadas desde o início.

Será um trabalho de adivinhação no início, mas com o tempo, como você tem estatísticas de uso adequadas, terá uma imagem mais clara.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.