Estou enfrentando o seguinte e não tenho certeza de quais são as melhores práticas.
Considere a seguinte tabela (que ficará grande):
id PK | giver_id FK | destinatário_id FK | encontro
Estou usando o InnoDB e, pelo que entendi, ele cria índices automaticamente para as duas colunas de chave estrangeira. No entanto, também farei muitas consultas em que preciso encontrar uma combinação específica de:
SELECT...WHERE giver_id = x AND recipient_id = t
.
Cada uma dessas combinações será única na tabela.
Há algum benefício em adicionar um índice de duas colunas sobre essas colunas ou os dois índices individuais, em teoria, seriam suficientes / iguais?
Respostas:
Se você tiver dois índices de coluna única, apenas um deles será usado em seu exemplo.
Se você tiver um índice com duas colunas, a consulta pode ser mais rápida (você deve medir). Um índice de duas colunas também pode ser usado como um índice de coluna única, mas apenas para a coluna listada primeiro.
Às vezes, pode ser útil ter um índice em (A, B) e outro índice em (B). Isso torna as consultas usando uma ou ambas as colunas mais rápidas, mas é claro que também usa mais espaço em disco.
Ao escolher os índices, você também precisa considerar o efeito na inserção, exclusão e atualização. Mais índices = atualizações mais lentas.
fonte
Um índice de cobertura como:
... significaria que o índice poderia ser usado se uma consulta fosse referida
giver_id
ou uma combinação degiver_id
erecipient_id
. Lembre-se de que os critérios de índice são baseados na extrema esquerda - uma consulta referente a apenasrecipient_id
não seria capaz de usar o índice de cobertura na instrução que forneci.Além disso, o MySQL pode usar apenas um índice por SELECT, portanto, um índice de cobertura seria o melhor meio de otimizar suas consultas.
fonte
MySQL can only use one index per SELECT
isso não é mais verdade, seria bom se você editasse sua resposta para ser atualizada.recipient_id
?INDEX (col1, col2, col3, col4)
, o índice será aplicado para pesquisas com umaWHERE
cláusula comocol1 = 'A'
oucol1 = 'A' AND col2 = 'B'
oucol1 = 'A' AND col2 ='B' AND col3 = 'C' AND col4 = 'D'
, mas este índice específico não será usado para nada comoWHERE col2 = 'B'
ouWHERE col3 = 'C' AND col4 = 'D'
porque os campos de pesquisa não são deixados na maior parte na definição do índice. Você teria que adicionar índices adicionais para cobrir esses campos.Se um dos índices de chave estrangeira já for muito seletivo, o mecanismo de banco de dados deve usar aquele para a consulta que você especificou. A maioria dos mecanismos de banco de dados usa algum tipo de heurística para escolher o índice ideal nessa situação. Se nenhum índice for altamente seletivo por si só, provavelmente faz sentido adicionar o índice construído em ambas as chaves, pois você diz que usará muito esse tipo de consulta.
Outra coisa a considerar é se você pode eliminar o campo PK nesta tabela e definir o índice de chave primária nos campos
giver_id
erecipient_id
. Você disse que a combinação é única, então possivelmente funcionaria (dadas muitas outras condições que só você pode responder). Normalmente, porém, acho que a complexidade adicionada não compensa o incômodo.fonte
Outra coisa a considerar é que as características de desempenho de ambas as abordagens serão baseadas no tamanho e na cardinalidade do conjunto de dados. Você pode descobrir que o índice de 2 colunas só percebe mais desempenho em um determinado limite de tamanho do conjunto de dados ou exatamente o oposto. Nada pode substituir as métricas de desempenho para o seu cenário exato.
fonte