Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Conselhos necessários para indexar corretamente uma tabela com muitos campos a serem pesquisados


Eu tenho uma tabela no trabalho com o mesmo tipo de coisa, muitas colunas e 1000 maneiras diferentes de selecionar. É um pesadelo. No entanto, descobri que existem certas combinações de filtros que são usadas com frequência. São aqueles para os quais eu criaria índices e deixaria os outros que raramente são usados ​​para rodar lentamente. No MSSQL, posso executar uma consulta para me mostrar as consultas mais caras que foram executadas no banco de dados, o mySQL deve ter algo semelhante. Depois de tê-los, crio um índice que cobre as colunas para acelerá-los. Eventualmente, você terá 90 por cento coberto. Eu, pessoalmente, nunca projetaria uma mesa assim novamente, a menos que tivesse um AK47 apontado para mim. (meus índices são 3 vezes maiores que os dados na tabela, o que é muito chato se você precisar adicionar um monte ou registros). Não tenho certeza de como eu redesenharia a tabela, meu primeiro pensamento seria dividir a tabela em duas , mas isso aumentaria as dores de cabeça em outros lugares.

Tabela de usuários (UserID, Nome)
1, Lisa
2, Jane
3, John

Tabela de atributos do usuário (UserID, AttributeName, AttributeValue)
1, EYES, Brown
1, GENDER, Female
2, EYES, Blue
2, GENDER, Female
3  EYES, Blue
3, GENDER, Male

Isso tornaria a identificação de atributos mais rápida, mas tornaria suas consultas menos fáceis de escrever.
SELECT UserID, COUNT(*) as MatchingAttributes
FROM   UserAttributes 
WHERE  (UserAttributes.AttributeName = 'EYES' AND UserAttributes.AttributeValue = 'Blue') OR
       (UserAttributes.AttributeName = 'GENDER' AND UserAttributes.AttributeValue = 'Female') 

Isso deve retornar o seguinte
UserID, MatchingAttributes
1, 1
2, 2
3, 1

Tudo o que você precisa fazer é adicionar um HAVING COUNT(*) =2 à consulta para selecionar apenas os IDs correspondentes. É um pouco mais complicado para selecionar, mas também oferece um recurso interessante, digamos que você filtre em 10 atributos e retorne todos aqueles que têm 10 correspondentes. Legal, mas diga que nenhum correspondeu 100%. Você poderia dizer ei, eu não encontrei nenhum que correspondesse, mas estes tinham 9 em 10 ou 90% de correspondência. (apenas certifique-se, se eu procurar por uma mulher loira de olhos azuis, não recebo uma mensagem dizendo que nenhuma foi encontrada, mas aqui estão as próximas correspondências mais próximas contendo caras loiras de olhos azuis com uma pontuação correspondente de 60%. ser muito chato)

Há mais coisas que precisam ser consideradas se você optar por dividir a tabela, como como armazenar atributos como números, datas e texto em uma única coluna? Ou são tabelas ou colunas separadas. Nenhuma resposta fácil, seja em mesa ampla ou em tabelas divididas.