Eu tenho uma tabela com 100k linhas
CREATE TABLE `small_table` ( `pk` int(11) NOT NULL AUTO_INCREMENT, `varc` varchar(255) DEFAULT NULL, texto `txt`, CHAVE PRIMÁRIA (`pk`) ) ENGINE=InnoDB AUTO_INCREMENT=103925 DEFAULT CHARSET=utf8
e eu executei a seguinte consulta
selecione varc,count(*) do grupo small_table por varc;
e eu tinha perfilado o mesmo
+-----------+----------+ | Situação | Duração | +-----------+----------+ | começando | 0,000060 | | verificando permissões | 0,000010 | | Mesas de abertura | 0,004685 | | iniciar | 0,000025 | | Bloqueio do sistema | 0,000006 | | otimizando | 0,000002 | | estatísticas | 0,000010 | | preparando | 0,000006 | | Criando tabela tmp | 0,000020 | | Resultado da ordenação | 0,000003 | | executando | 0,000005 | | Envio de dados | 0,001720 | | Criando índice de classificação | 0,000033 | | fim | 0,000002 | | fim da consulta | 0,000004 | | removendo a tabela tmp | 0,000004 | | fim da consulta | 0,000002 | | mesas de fechamento | 0,000004 | | libertar artigos | 0,000015 | | limpeza | 0,000007 | +-----------+----------+
O perfil tem Criando o estado da tabela tmp (por documentos do mysql, significa que uma tabela tmp é criada na memória ou no disco). Minha dúvida é que o perfil não tem Copiando para o estado da tabela tmp (durante o estado, O servidor estará copiando para uma tabela temporária na memória.) Minha suposição é que ele tenha criado uma tabela tmp e não a esteja utilizando. Estou certo?
Onde está meu estado Copiando para a tabela tmp ?
Só tem um nome um pouco diferente. É "Criando tabela tmp", que também faz mais sentido. O MySQL sabe que uma tabela temporária será necessária, então ele a gera rapidamente. O nome do estado "copiando para a tabela tmp" é apenas mal escolhido.
Eu costumo achar o Perfil inútil. Normalmente, "enviar dados" é a entrada principal. Isso não dá nenhuma pista do que deve ser corrigido para melhorar o desempenho.
Embora não haja "copiando para a tabela tmp", há uma "tabela de abertura" bastante grande. Mas nenhuma pista se é sua mesa ou uma mesa tmp . Existe "Criando tabela tmp". A tabela tmp pode estar na memória; ou seja, nenhuma tabela de disco real.
Existem duas maneiras de fazer sua consulta -
Construa um hash na memória de todos os
varcs
; varrer a tabela, incrementando entradas no hash; classificar o resultado; entregue Isso.Classifique a tabela primeiro (isso envolve uma tabela tmp na RAM no seu caso); em seguida, uma varredura de tabela simples, construindo um
COUNT
de cada vez.Não sei quando o Optimizer escolhe um sobre o outro. Mas sempre envolve uma varredura de tabela, que tende a ser a maior parte do tempo gasto (apesar de não aparecer no Perfil).
Se você tivesse
INDEX(varc)
, teria feito:Mas... Quando uma consulta leva menos de 10 ms, não vale a pena dissecar -- há muito pouco a ser ganho e muito pouco que vale a pena otimizar.