Pergunta

Eu tenho essa tabela a seguir:

Matches -> match_id, team_a_id , team_b_id, score

Esta tabela irá gravar os jogos entre duas equipes (equipe A e equipe B).No entanto, às vezes, A equipa A jogar como o anfitrião e, por vezes, da equipa B joga como o anfitrião.Portanto, quando eu tentei encontrar o histórico de partidas entre equipa a e da equipa b.O que eu atualmente estou fazendo o que é para

select * from matches where (team_a_id = 1 and team_b_id = 2) or (team_a_id = 2 and team_b_id = 1);

Existe alguma melhor aproximação para o caso?Como para a consulta acima, estou certo de incluir o índice de combinação team_a_id e team_b_id?Mas mesmo assim, então eu ainda tenho um Lógico OU condição entre AB OU BA.

Como alternativa, Eu tenho uma outra idéia, que é ter de outra tabela, vamos dizer que a história

History -> team_hash, match_id

Eu manualmente construir team_hash onde hash(a,b) == hash(b,a).Mas este resultado ligeiramente mais lento insira mas a leitura mais rápida.Ou é realmente a leitura mais rápida?

Foi útil?

Solução

Assumindo que há um índice composto em {team_a_id, team_b_id}, o DBMS pode executar a instrução de SQL usando apenas duas índice de procura (uma para o team_a_id = 1 and team_b_id = 2 e o outro para o team_a_id = 2 and team_b_id = 1), que é muito rápido.Eu não espero que você deve achar que o desempenho deficiente.


No entanto, há uma maneira de eliminar um desses índice de procura.Adicionar uma restrição de...

CHECK(team_a_id < team_b_id)

...e codificar uma "direção" (i.é.qual a equipa que é host) em um campo separado, se necessário.Dessa forma, você sabe team_a_id = 2 and team_b_id = 1 nunca pode ser verdade, então você só precisa de pesquisa em team_a_id = 1 and team_b_id = 2.


"Simétrico" hash é uma idéia legal, mas:

  • A correção do hash não pode ser imposta de forma declarativa - você precisará fazê-lo através de um trigger ou no nível do aplicativo.
  • É um redundante de dados.Você vai precisar para manter team_a_id e team_b_id de qualquer maneira para resolver hash conflitos.Maiores dados com eficiência significa menor cache.
  • Ele pode realmente aumentar o número de índices - a aplicação eficaz da integridade referencial provavelmente exigirá índices team_a_id e team_b_id mesmo se você não precisar deles para o real consulta SQL.Além de colocar mais pressão no cache, cada índice adicional deve ser mantida, potencialmente prejudicando a INSERÇÃO/ATUALIZAÇÃO/EXCLUSÃO de desempenho.A situação é especialmente grave em InooDB onde você não pode desativar o agrupamento, assim, índices secundários tendem a ser mais caros do que na pilha baseado em tabelas (consulte o "Desvantagens de cluster" em este artigo).

Outras dicas

Você também pode fazer a sua cláusula WHERE algo como isto

((team_a_id = 1 and team_b_id = 2) or (team_a_id = 2 and team_b_id = 1))
AND team_a_id IN (1,2) AND team_b_id IN (1,2)

desta forma, será possível a utilização de um índice como (team_a_id,team_b_id).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top