Tenho tentado otimizar minha mesa, mas ainda não consigo obter os resultados desejados.
CREATE TABLE IF NOT EXISTS `puzzles` (
`puzzleID` int(7) NOT NULL,
`puzzleMask` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`puzzleScore` int(7) NOT NULL,
`time` int(11) NOT NULL DEFAULT '0',
`hour` int(11) NOT NULL DEFAULT '0',
`ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`Iip` int(11) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`puzzleID`, `puzzleMask`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
A combinação de ID e Mask deve ser única, enquanto ID é um número inteiro aleatório e Mask uma combinação de números com comprimento máximo de 30. Hora é o registro de data e hora unix e hora é "time - (time % 3600)" (a hora em qual a linha foi enviada). ip é o endereço IP de um servidor (cerca de 20 servidores) e Iip é INET_ATON( ip ).
Esses 20 servidores enviam informações de quebra-cabeça para esse banco de dados. Gostaria de mostrar estatísticas ao vivo das informações enviadas (5 a 10 registros por segundo).
Para isso, utilizo duas consultas principais que precisam ser as mais otimizadas possíveis:
Obter estatísticas totais
SELECT COUNT(*) AS total, MAX(puzzleScore) AS maxScore, hour FROM puzzles WHERE hour => #startHour# GROUP BY hour
Obtenha estatísticas dependentes do servidor
SELECT COUNT(*) AS total, MAX(puzzleScore) AS maxScore, hour FROM puzzles WHERE hour => #startHour# AND Iip = INET_ATON("#IPAddress#") GROUP BY hour
Minha pergunta é, quais índices usar? Eu tentei muitas coisas agora, mas com o banco de dados aumentando rapidamente, o tempo de tentativa e erro acabou... por exemplo, preciso de um índice separado para o puzzleScore, já que quero o máximo? ou preciso combiná-lo em outro índice?
Além disso, é verdade que usar uma chave primária (puzzleID e puzzleMask) em combinação com INSERT IGNORE INTO... ?
obrigada
O que você tentou? Essas duas consultas estão sendo executadas lentamente? Existem outras operações que se tornaram um problema? Como você tem um sistema ativo, em vez de especular sobre o que pode estar causando um problema, você pode adicionar alguns perfis para ter certeza.
Sua primeira consulta pode ser respondida por um índice em
( Hour, PuzzleScore )
, nessa ordem. Seu segundo exigiria a adição deIip
; já que deveria ter excelente cardinalidade, eu colocaria primeiro:( Iip, Hour, PuzzleScore )
. Verifique comEXPLAIN
para confirmar se os índices são realmente usados; dependendo da contagem de linhas e cardinalidade, pode não haver benefício.Como você está consultando de
Hour
qualquer maneira, consideraria agrupar nesse campo (em conjunto com um campo exclusivo ou uma combinação de campos para garantir a exclusividade, é claro).Advertência: Trabalho principalmente em SQL-Server, não sou especialista em MySQL.