Melhor do MyISAM e InnoDB

17

É possível fazer com que o InnoDB use índices iguais ao MyISAM em vez do índice clusterizado devido à limitação de RAM enquanto se beneficia de seu desempenho de simultaneidade?

Rick James
fonte

Respostas:

14

O gen_clust_index (índice clusterizado) sob o capô do InnoDB abriga entradas de chaves primárias junto com rowids. O que é interessante sobre o uso do gen_clust_index é o fato de que quaisquer índices não exclusivos criados por você sempre terão um rowid correspondente para o gen_clust_index de uma tabela. Portanto, sempre há pesquisas de índice duplas, uma para o índice secundário e outra para o gen_clust_index.

Qualquer tentativa de melhorar o layout de uma tabela ou chave primária é anulada por causa do gen_clust_index, ou pelo menos resultados marginais, na melhor das hipóteses.

EXEMPLO

Algumas pessoas tentam classificar um MyISAM em ordem PRIMARY KEY. De acordo com o MySQL Database Design and Tuning, parágrafo 7, sob o subtítulo "Armazenando uma tabela em ordem de índice":

Se você recupera frequentemente grandes intervalos de dados indexados de uma tabela ou classifica resultados de forma consistente na mesma chave de índice, considere executar o myisamchk com a opção --sort-records. Ao fazer isso, diga ao MySQL para classificar os dados da tabela na mesma ordem física que o índice e pode ajudar a acelerar esse tipo de operação. Como alternativa, você pode combinar a instrução ALTER TABLE com uma opção ORDER BY uma coluna específica para obter os mesmos resultados.

Concedido, isso funciona e funciona efetivamente para o MyISAM . Você pode executar ALTER TABLE ... ORDER BY col1, col2, ..., coln no InnoDB, onde as colunas podem ou não ser as da PRIMARY KEY. Isso não produzirá resultados mais rápidos para o InnoDB porque ... isso mesmo ... você deve consultar o gen_clust_index a cada vez.

Algumas pessoas podem corrigir o formato de linha da tabela ALTER TABLE mydb.mytb ROW_FORMAT=Fixed;e obter um aumento de 20% no desempenho de leitura sem outras alterações. Isso funciona e funciona efetivamente para o MyISAM . Isso não produzirá resultados mais rápidos para o InnoDB porque ... isso mesmo ... você deve consultar o gen_clust_index a cada vez.

Você pode executar o seguinte em uma tabela do InnoDB chamada mydb.mytb:

CREATE TABLE mydb.mytc LIKE mydb.mytb;
INSERT INTO mydb.mytc SELECT * FROM mydb.mytb ORDER BY col1,col2,...coln;
ALTER TABLE mydb.mytb RENAME mydb.mytd;
ALTER TABLE mydb.mytc RENAME mydb.mytb;
DROP TABLE mydb.mytd;

Isso colocará a tabela em ordem rowid no gen_clust_index. Isso pode produzir resultados marginais para o InnoDB, na melhor das hipóteses, porque ... isso mesmo ... você deve consultar o gen_clust_index a cada vez.

Agora, vamos ficar um pouco ridículos. Existe uma interface NoSQL para consultar (somente SELECT) MyISAM e InnoDB, denominada interface HandlerSocket (anteriormente denominada HANLDER) . Isso fornece acesso a dados que permitem ignorar todos os protocolos SQL, ACID e MVCC . Embora seja possível, IMHO MUITO COMPLICADO AO CÓDIGO E À MANUTENÇÃO. AFAIK, não há nada impresso indicando se a interface HandlerSocket interage com o gen_clust_index ou não.

Em resumo, existem muitas maneiras de esfolar um gato. Nesse caso, você não pode se apossar do gato (o gen_clust_index). Eu acho que é por isso que o MyISAM continua a existir por seu desempenho de leitura, sua flexibilidade na ordenação de tabelas, no formato de linha da tabela e nas ferramentas de suporte. O InnoDB is permanecerá projetado de acordo com sua natureza compatível com ACID até que uma alma corajosa pegue o código fonte do InnoDB e o transforme em algo que tenha o melhor do MyISAM e do InnoDB .

RolandoMySQLDBA
fonte
3

O índice clusterizado é talvez o motivo do desempenho de simultaneidade do InnoDB nas unidades de rotação tradicionais.

O acesso a uma linha através do índice em cluster é rápido, porque os dados da linha estão na mesma página em que a pesquisa do índice leva. Se uma tabela for grande, a arquitetura de índice em cluster geralmente salva uma operação de E / S de disco quando comparada às organizações de armazenamento que armazenam dados de linha usando uma página diferente do registro de índice. (Por exemplo, o MyISAM usa um arquivo para linhas de dados e outro para registros de índice.)

E / S de disco é cara. Portanto, reduzir esse é um grande benefício para melhorar a simultaneidade.

Se a E / S do disco começar a ficar mais barata e menos gargalo (por exemplo, à medida que a tecnologia SSD se tornar mais estável), a Oracle poderá decidir alterar a forma como os índices do InnoDB funcionam. O mais provável é que permaneça o mesmo, porque a mesma tecnologia tornará a 'limitação da RAM' menos um problema.

Derek Downey
fonte
3

Resposta curta: Não.

Clusters do InnoDB por meio da chave primária e, na ausência de uma chave primária, ele escolhe o primeiro índice exclusivo. Na ausência de um índice exclusivo, ele cria uma chave oculta de 6 bytes para cluster.

Quando você tem a chave oculta de 6 bytes, quaisquer índices secundários se referem a essa chave, em vez de ponteiros exatos para os locais das linhas (como no MyISAM), então você acaba com uma passagem de chave secundária e, em seguida, uma passagem de chave primária para encontrar seus registros .


Para extrapolar um pouco da sua pergunta, suponho que você esteja preocupado com o ajuste da memória em uma árvore, porque, para pesquisar com eficiência, todos os nós raiz devem estar na memória, pois você sempre precisa seguir esse caminho para encontrar as páginas da folha?

Isso é verdade, mas um consolo é que os bancos de dados comerciais tentam tornar suas árvores tão gordas quanto possível, em vez de profundas. Tente executar o xtrabackup --stats nos seus dados para ver. Por exemplo:

<INDEX STATISTICS>
  table: test/table1, index: PRIMARY, space id: 12, root page 3
  estimated statistics in dictionary:
    key vals: 25265338, leaf pages 497839, size pages 498304
  real statistics:
     level 2 pages: pages=1, data=5395 bytes, data/pages=32%
     level 1 pages: pages=415, data=6471907 bytes, data/pages=95%
        leaf pages: recs=25958413, pages=497839, data=7492026403 bytes, data/pages=91%

Havia 497839 páginas em folha (~ 8 GB), mas apenas 416 páginas acima (6,5 MB). Eu executei esse comando algumas vezes em dados de produção e sempre me surpreende quando tenho milhões de bilhões de registros e apenas nível 1-3 páginas + folhas.

Morgan Tocker
fonte