Esta consulta: select count(*) from planner_event
leva muito tempo para ser executada - tanto tempo, desisti e a matei antes de terminar. No entanto, quando executo explain select count(*) from planner_event
, posso ver uma coluna na saída com o número de linhas (14m).
Como é que a explicação pode obter o número de linhas instantaneamente, mas count(*) leva muito tempo para ser executado?
O Explain está usando estatísticas coletadas anteriormente (usadas pelo otimizador de consulta). Fazendo um
select count(*)
lê TODOS os blocos de dados.Aqui está uma maneira barata de obter uma contagem estimada de linhas:
Mesmo se você fez
select count(id)
, ainda pode levar muito tempo, a menos que você tenha um índice secundárioid
(assumindo também queid
é uma CHAVE PRIMÁRIA). Como todos os dados (incluindo dados de linha) são armazenados em índices B-Tree, executar umselect count(PK_COLUMN)
ainda é uma quantidade considerável de E/S (precisa ler todas as páginas de dados). Se você tiver um índice secundário no campo PK, ele poderá executar menos IO para realizar uma contagem.O Explain obtém o número de algumas "estatísticas" que são usadas para estimar coisas para o Optimizer. Esse número pode estar longe de ser correto - às vezes vejo que é mais do que um fator de 2 (maior ou menor) do que o valor exato.
Executar o
COUNT(*)
em uma tabela InnoDB deve varrer a tabela para evitar erros de contagem de registros que estão ocupados sendo inseridos/excluídos por outras conexões, mas ainda não "confirmados". Na verdade, é bom fazer uma varredura completa em algum índice, não necessariamente em toda a tabela (que contém oPRIMARY KEY
).Quanta memória RAM você tem? Qual é o valor de
innodb_buffer_pool_size
? Pode ajudar se isso fosse cerca de 70% da RAM.