Slow INSERT na tabela InnoDB com o valor aleatório da coluna PRIMARY KEY
Para meu site, uso a API PHP para Flickr http: //www.flickr.com/services/api). Essa API fornece vários métodos úteis para obter fotos em determinadas posições GPS.
A chamada para os métodos da API se parece com URL com parâmetros específicos, como latitude, longitude, chave da API, raio, classificação etc. Digamos, será comohttp://api.flickr.com/method?lat=0.0&lon=0.0&radius=10
@My website faz mais de 200.000 chamadas para a API para gerar várias páginas com fotos do Flickr. É uma pressão muito forte na API, portanto, criei um cache de resultados no banco de dados mySQL.
O esquema simplificado da tabela InnoDB com cache é:
char(32) request
datetime expires // 2-3 days
text response // serialized data from API response
Onderequest
é uma CHAVE PRIMÁRIA e representa um hash MD5 de um URI de solicitação. Outros campos são bem simples:)
O problema surge quando a tabela se torna grande o suficiente, digamos, mais de 100.000 linhas. NovoINSERTs
demore até 2 segundos (e até 6 (!) segundo com 1.000.000 de linhas
Tanto quanto eu entendo, o problema é com o PRIMARY INDEX e o mecanismo sendo o InnoDB. Sempre que uma nova solicitação é inserida, o mecanismo do InnoDB reconstrói o índice da árvore e move os dados, porque MD5 (solicitação) é um valor realmente aleatóri
Então ... A questão é se existe uma maneira melhor de armazenar esses pedidos em cache? Ou talvez eu deva mudar para o mecanismo MyISAM? Ou talvez eu deva tentar o pseudo-particionamento e criar várias tabelas para resolver o problema? Ou pode ser apenas usar não um índice BTREE, mas HASH?
Todas as idéias são bem-vindas!
Editar
Ok, tentei alterar a tabela como Furicane e Johan sugeriram, mas ainda sem sorte - os INSERTs levam até 3 segundos. Atualmenterequest
campo tornou-se um índice não exclusivo normal e novosid
coluna @ foi adicionada como PRIMARY KEY com incremento automático. Também tentei adicionar 4 partições nesta tabela com os mesmos resultado
Acho que esse índice emrequest
field ainda é um gargalo. A única maneira que vejo atualmente é determinar todos os parâmetros possíveis, adicioná-los como colunas a uma tabela e criar um índice nele
Algumas outras idéias? :)
Edit 2:
Salman A nos comentários abaixo disse que sua tabela semelhante tem um desempenho muito melhor (~ 0,03 para inserção). Esse problema pode estar na carga de E / S no sistema. Embora eu não possa carregar muita carga nele.
iostat
resultados
avg-cpu: %user %nice %system %iowait %steal %idle
22.94 0.71 8.42 8.50 0.00 59.43
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 38.01 151.04 114.32 1383655437 1047309046
iotop
resultados
Total DISK READ: 152.91 K/s | Total DISK WRITE: 197.67 K/s
Com o mySQL no topo da lista, tanto para escrever quanto para ler. Talvez meus discos estejam quase mortos? Como posso verificar o desempenho dos discos?