Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL EXPLAIN 'type' muda de 'range' para 'ref' quando a data na instrução where é alterada?


Diferentes estratégias de pesquisa fazem sentido para dados diferentes. Em particular, verificações de índice (como intervalo) geralmente precisam fazer uma busca para realmente ler a linha. Em algum momento, fazer todas essas buscas é mais lento do que não usar o índice.

Tomemos um exemplo trivial, uma tabela com três colunas:id (chave primária), nome (indexado), aniversário. Diga que tem muitos dados. Se você pedir ao MySQL para procurar o aniversário de Bob, ele pode fazer isso rapidamente:primeiro, ele encontra Bob no índice de nomes (isso leva algumas buscas, log(n) onde n é a contagem de linhas), então uma busca adicional para leia a linha real no arquivo de dados e leia o aniversário dela. Isso é muito rápido e muito mais rápido do que escanear a mesa inteira.

Em seguida, considere fazer um name like 'Z%' . Essa é provavelmente uma porção bastante pequena da tabela. Portanto, é ainda mais rápido encontrar onde os Zs começam no índice de nomes e, para cada um, procurar o arquivo de dados para ler a linha. (Esta é uma varredura de intervalo).

Finalmente, considere pedir todos os nomes que começam com M-Z. Isso é provavelmente cerca de metade dos dados. Ele poderia fazer uma varredura de intervalo e, em seguida, muito de buscas, mas buscar aleatoriamente no arquivo de dados com o objetivo final de ler metade das linhas não é o ideal:seria mais rápido fazer apenas uma grande leitura sequencial no arquivo de dados. Portanto, neste caso, o índice será ignorado.

Isso é o que você está vendo - exceto no seu caso, há outra chave na qual ela pode recorrer. (Também é possível que ele possa realmente usar o índice de data se não tiver o outro, ele deve escolher o índice que for mais rápido. Cuidado que o otimizador do MySQL geralmente comete erros nisso.)

Então, em suma, isso é esperado. Uma consulta não diz como para recuperar os dados, em vez disso, diz o que dados para recuperar. O otimizador do banco de dados deve encontrar a maneira mais rápida de recuperá-lo.

Você pode encontrar um índice em ambos colunas, na ordem (public_key,created_on_date) é o preferido em ambos os casos e acelera sua consulta. Isso ocorre porque o MySQL só pode usar um índice por tabela (por consulta). Além disso, a data vai no final porque uma varredura de intervalo só pode ser feita de forma eficiente na última coluna em um índice.

[InnoDB realmente tem outra camada de indireção, eu acredito, mas apenas confundiria o ponto. Não faz diferença para a explicação.]