Analisando um servidor em busca de consultas para otimizar, encontrei a query abaixo.
SELECT SQL_CALC_FOUND_ROWS t.id FROM tabela t ORDER BY t.id LIMIT 10 OFFSET 10
Sem saber do que se tratava o modificador SQL_CALC_FOUND_ROWS pesquisei, e aqui encontrei. Vamos testar!
Usando uma tabela com mais de 8 milhões de registros, preparei os comandos.
SELECT SQL_CALC_FOUND_ROWS t.* FROM tabela t ORDER BY t.id LIMIT 10 OFFSET 10; SELECT FOUND_ROWS(); >> 9
E não funcionou; o returno era sempre 9. Depois de quebrar um pouco a cabeça, substitui o t.* por t.id, como encontrei na query original.
SELECT SQL_CALC_FOUND_ROWS t.id FROM tabela t ORDER BY t.id LIMIT 10 OFFSET 10; SELECT FOUND_ROWS(); >> 8317125
Agora sim. Não funcionou com *, o artigo não menciona nada sobre isso, pelo contrário, os exemplos contidos usam *. Mas enfim, funcionou.
Vamos comparar o desempenho com a forma tradicional, ou seja, SELECT depois COUNT.
Opção FOUND_ROWS() Opção tradicional
SELECT SQL_CALC_FOUND_ROWS t.id SELECT t.id
FROM tabela t FROM tabela t
WHERE t.tipo = 1 WHERE t.tipo = 1
ORDER BY t.id ORDER BY t.id
LIMIT 10 LIMIT 10
OFFSET 110; OFFSET 110;
SELECT FOUND_ROWS(); SELECT COUNT(t.id)
FROM tabela t
WHERE t.tipo = 1;
Execução 1
SQL query: 6,191 SQL query: 6,359
SQL query: 0 SQL query: 6,266
Execução 2
SQL query: 7,321 SQL query: 0,047
SQL query: 0 SQL query: 7,049
Execução 3
SQL query: 6,323 SQL query: 6,407
SQL query: 0 SQL query: 6,343
Apenas na segunda execução o tempo foi similar, nas outras duas a dupla SQL_CALC_FOUND_ROWS e FOUND_ROWS() executou em metade do tempo.
Quando já estava me animando, fui verificar aquele mesmo artigo, mas para o MySQL 8, aqui, e estes comandos foram tornados obsoletos a partir da versão 8.0.17. De acordo com o próprio artigo, algumas otimizações são aplicadas em COUNT(*)
E aí, vale a pena usar? Ainda não temos a opção de comentários aqui, mas pode me enviar um e-mail ou me chamar aqui se preferir.