De onde o MySQL Query Optimizer lê as estatísticas do índice?


14

Estou tentando determinar de onde o otimizador do MySQL obtém a lista de índices disponíveis para uma tabela quando estima o custo de (prepara) uma consulta.


+1 para essa boa pergunta, pois os desenvolvedores e os DBAs devem pausar e pensar em como as estatísticas do índice são compiladas e armazenadas.
RolandoMySQLDBA

Para referência, no site de documentação do mysql: < dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html >> ANALYZE TABLEdetermina a cardinalidade do índice (conforme exibido na coluna de SHOW INDEXsaída Cardinality ) executando oito mergulhos aleatórios para cada das árvores de índice e atualizando as estimativas de cardinalidade do índice de acordo. Como essas são apenas estimativas, execuções repetidas de ANALYZE TABLE podem produzir números diferentes. Isso ANALYZE TABLEacelera as tabelas do InnoDB, mas não é 100% preciso, pois não leva em consideração todas as linhas.
Chen Xie

Respostas:


6

A resposta direta para isso seria

information_schema.statistics

mysql> desc information_schema.statistics;
+---------------+---------------+------+-----+---------+-------+
| Field         | Type          | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+-------+
| TABLE_CATALOG | varchar(512)  | NO   |     |         |       |
| TABLE_SCHEMA  | varchar(64)   | NO   |     |         |       |
| TABLE_NAME    | varchar(64)   | NO   |     |         |       |
| NON_UNIQUE    | bigint(1)     | NO   |     | 0       |       |
| INDEX_SCHEMA  | varchar(64)   | NO   |     |         |       |
| INDEX_NAME    | varchar(64)   | NO   |     |         |       |
| SEQ_IN_INDEX  | bigint(2)     | NO   |     | 0       |       |
| COLUMN_NAME   | varchar(64)   | NO   |     |         |       |
| COLLATION     | varchar(1)    | YES  |     | NULL    |       |
| CARDINALITY   | bigint(21)    | YES  |     | NULL    |       |
| SUB_PART      | bigint(3)     | YES  |     | NULL    |       |
| PACKED        | varchar(10)   | YES  |     | NULL    |       |
| NULLABLE      | varchar(3)    | NO   |     |         |       |
| INDEX_TYPE    | varchar(16)   | NO   |     |         |       |
| COMMENT       | varchar(16)   | YES  |     | NULL    |       |
| INDEX_COMMENT | varchar(1024) | NO   |     |         |       |
+---------------+---------------+------+-----+---------+-------+
16 rows in set (0.01 sec)

Você pode selecionar a partir dessa tabela com

SELECT * FROM information_schema.statistics
WHERE table_schema='mydb' AND table_name='mytable';

ou veja as estatísticas fazendo

MOSTRAR ÍNDICES DE mydb.mytable;

Lembre-se de que esta tabela nem sempre é precisa em um ambiente com muita gravação. Periodicamente, você terá que executar o ANALYZE TABLE em todas as tabelas MyISAM que são atualizadas com freqüência. Caso contrário, o MySQL Query Optimizer, que depende de information_schema.statistics, às vezes pode fazer más escolhas ao desenvolver planos EXPLAIN para consultas. As estatísticas do índice devem estar o mais atualizadas possível.

ANALYZE TABLE ABSOLUTAMENTE SEM EFEITO nas tabelas do InnoDB. Todas as estatísticas de índice do InnoDB são computadas sob demanda por meio de mergulhos nas páginas do BTREE. Portanto, quando você executa SHOW INDEXES FROM em uma tabela do InnoDB, as cardinalidades exibidas são sempre aproximações.

UPDATE 2011-06-21 12:17 EDT

Para esclarecimentos sobre ANALYZE TABLE, deixe-me reformular. A execução de ANALYZE TABLE nas tabelas do InnoDB é completamente inútil. Mesmo se você executou ANALYZE TABLE em uma tabela InnoDB, o mecanismo de armazenamento InnoDB executa mergulhos no índice para aproximações de cardinalidade repetidas vezes, destruindo assim as estatísticas que você acabou de compilar . De fato, a Percona realizou alguns testes no ANALYZE TABLE e chegou a essa conclusão também.


5

Re: ANALYZE TABLE ABSOLUTAMENTE SEM EFEITO contra tabelas InnoDB.

Não tenho certeza se esta afirmação é verdadeira. Temos muita leitura e gravação de tabelas innodb e quando o otimizador mysql faz a má escolha, a saída de explicação da consulta mostra uma estratégia ruim. e também SHOW INDEXES da tabela Innodb mostra muita variação em seus valores de cardinalidade. Mas executar um comando ANALYZE nessas tabelas innodb corrige o plano de explicação e também tira o comportamento da variação da cardinalidade. Não sei se o comando ANALYZE table nas tabelas Innodb ajuda o tempo todo ou não, mas, no nosso caso, ajudou 99% do tempo.

Eliminamos completamente a má escolha do otimizador mysql, incluindo o "STRAIGHT_JOIN" em nossas consultas. Este otimizador forçado do mysql não deve fazer más escolhas ou quaisquer escolhas, mas apenas seguir a condição JOIN do que definimos na consulta como está.


Atualizei minha resposta para destacar a inutilidade de ANALYZE TABLE nas tabelas do InnoDB.
RolandoMySQLDBA

Concordo com sua resposta quando você mencionou a variação na cardinalidade. Era exatamente o que eu estava dizendo quando disse aproximações de cardinalidade.
RolandoMySQLDBA

Eu também precisava mencionar que o uso de dicas em consultas nem sempre é a melhor coisa a fazer quando o MySQL Query Optimizer tende a eliminá-las às vezes. Aqui está um link para o que acontece internamente para consultas que podem realmente fazer desaparecer dados em partes de planos de consulta: dba.stackexchange.com/questions/1371/...
RolandoMySQLDBA

2

ANALYZE TABLE for MyISAM varre a tabela inteira e reconstrói as estatísticas, que são salvas (acho) no arquivo .MYI. Raramente é necessário.

ANALYZE TABLE for InnoDB não algo - ele faz o mergulho mencionado. O problema é que isso pode ajudar, pode piorar as coisas ou (provavelmente) não fará nenhuma diferença visível (exceto nas cardinalidades).

As versões mais recentes prometem permitir alterar as 8 sondas não tão aleatórias para (1) mais aleatórias, (2) permitir que você altere o "8" (existem prós e contras disso!) E (3) salvar nas reinicializações.

Conclusão: o InnoDB ainda não entendeu direito. ANALISAR quando lhe apetecer, mas não prenda a respiração.

Atualizar

Reformular ... ANALYZE TABLEtem um efeito temporário (possivelmente benéfico, possivelmente não) nas otimizações das tabelas do InnoDB.

"Versão mais recente": a partir das versões 5.6.6 (2012) e MariaDB 10.1 (2014), as estatísticas são tratadas muito melhor e ANALYZEagora são (1) menos necessárias e (2) mais permanentes.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.