Como otimizar os índices mysql para que as operações INSERT aconteçam rapidamente em uma tabela grande com freqüentes gravações e leituras?

Eu tenho uma mesalista de observação contendo hoje quase 3 mil registros.

mysql>  select count(*) from watchlist;
+----------+
| count(*) |
+----------+
|  2957994 |
+----------+

É usado como um registro para registrar visualizações de páginas de produtos em um grande site de comércio eletrônico (mais de 50.000 produtos). Ele registra o productID do produto visualizado, o endereço IP e USER_AGENT do visualizador. E um timestamp de quando isso acontece:

mysql> show columns from watchlist;
+-----------+--------------+------+-----+-------------------+-------+
| Field     | Type         | Null | Key | Default           | Extra |
+-----------+--------------+------+-----+-------------------+-------+
| productID | int(11)      | NO   | MUL | 0                 |       |
| ip        | varchar(16)  | YES  |     | NULL              |       |
| added_on  | timestamp    | NO   | MUL | CURRENT_TIMESTAMP |       |
| agent     | varchar(220) | YES  | MUL | NULL              |       |
+-----------+--------------+------+-----+-------------------+-------+

Os dados são então relatados em várias páginas do site, tanto no back-end (por exemplo, verificando o que o GoogleBot está indexando), quanto no front-end (por exemplo, uma barra lateral para "Produtos visualizados recentemente" e uma página mostrando aos usuários " As pessoas da sua região também gostaram "etc.).

Para que essas páginas de "relatórios" e barras laterais sejam carregadas rapidamente, coloco índices em campos relevantes:

mysql> show indexes from watchlist;
+-----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table     | Non_unique | Key_name  | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| watchlist |          1 | added_on  |            1 | added_on    | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
| watchlist |          1 | productID |            1 | productID   | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
| watchlist |          1 | agent     |            1 | agent       | A         |        NULL |     NULL | NULL   | YES  | BTREE      |         |
+-----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

Sem o INDEXES, páginas com a barra lateral, por exemplo, gastariam cerca de 30-45sec executando uma consulta para obter os 7 ProductIDs mais recentes. Com os índices, leva <0.2s.

O problema é quecom o INDEXES as páginas do produto estão demorando mais e mais para carregar, porque à medida que a tabela cresce, as operações de gravação estão levando mais de 5 segundos. Além disso, há um pico nomysqld processo no valor de 10 a 15% da CPU disponível cada vez que uma página do produto é visualizada (aproximadamente uma vez a cada 2 segundos). Nós já tínhamos que atualizar o hardware do servidor porque em um servidor anterior ele estava atingindo 100% e fazia o mysqld travar.

Meu plano é tentar uma solução de 2 mesas. Uma tabela para operações INSERT e outra para operações SELECT. eu planeiopurga a tabela INSERT sempre que atingir 1.000 registros usando um TRIGGER e copiar os 900 registros mais antigos para a tabela SELECT. As páginas do relatório são uma mistura de análise em tempo real (vista recentemente) e (qual região), mas as páginas em tempo real tendem a precisar apenas de um punhado de registros novos, enquanto as páginas analíticas não precisam saber sobre as mais recentes. tendência (ou seja, últimas mil visualizações). Então eu posso usar a pequena mesa para o primeiro e a grande mesa para os últimos relatórios.

Minha pergunta: Esta é uma solução ideal para este problema?

Além disso: Com TRIGGERS no MySQL é possívellegal o trigger_statement para que demore mais, mas não consome muito CPU? Correria umtrabalho cron a cada 30min que é picado, e que executa a limpeza, se necessário, ser uma solução melhor?

questionAnswers(6)

yourAnswerToTheQuestion