Quando você limita o número de linhas a serem retornadas por uma consulta SQL, geralmente usada em paginação, existem dois métodos para determinar o número total de registros:
Método 1
Inclua a SQL_CALC_FOUND_ROWS
opção no original SELECT
e obtenha o número total de linhas executando SELECT FOUND_ROWS()
:
SELECT SQL_CALC_FOUND_ROWS * FROM table WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();
Método 2
Execute a consulta normalmente e obtenha o número total de linhas executando SELECT COUNT(*)
SELECT * FROM table WHERE id > 100 LIMIT 10;
SELECT COUNT(*) FROM table WHERE id > 100;
Qual método é o melhor / mais rápido?
fonte
SQL_CALC_FOUND_ROWS
demora de 20 segundos; o uso de umaCOUNT(*)
consulta separada levou menos de 5 segundos (para consultas de contagem + resultados).SQL_CALC_FOUND_ROWS
será mais rápido, pergunto-me em que situações (se houver) ela é realmente mais rápida!tblA
,tblB
,tblC
,tblD
,tblY
ONDE tblA.b = tblC.id E tblA.c = tblB.id E tblA.d = tblD.id E tblA.y = tblY.idid
), ela precisou de 0,25 sozinha.FOUND_ROWS()
isso foi preterido no MySQL 8.0.17. Veja também a resposta de @ madhur-bhaiya.Ao escolher a "melhor" abordagem, uma consideração mais importante que a velocidade pode ser a manutenção e a correção do seu código. Nesse caso, é preferível SQL_CALC_FOUND_ROWS porque você precisa manter apenas uma única consulta. O uso de uma única consulta impede completamente a possibilidade de uma diferença sutil entre as consultas principal e a contagem, o que pode levar a uma COUNT imprecisa.
fonte
O MySQL começou a descontinuar a
SQL_CALC_FOUND_ROWS
funcionalidade com a versão 8.0.17 em diante.Portanto, é sempre preferível considerar a execução de sua consulta com
LIMIT
e, em seguida, uma segunda consulta comCOUNT(*)
e semLIMIT
para determinar se há linhas adicionais.Dos documentos :
Além disso,
SQL_CALC_FOUND_ROWS
foi observado que há mais problemas em geral, conforme explicado no MySQL WL # 12615 :fonte
LOCK TABLES <tablename>
eUNLOCK TABLES
. Terceira opção e (melhor IMHO) é repensar a paginação. Leia: mariadb.com/kb/en/library/pagination-optimizationDe acordo com o seguinte artigo: https://www.percona.com/blog/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/
Se você tiver um INDEX na sua cláusula where (se o id estiver indexado no seu caso), é melhor não usar SQL_CALC_FOUND_ROWS e, em vez disso, use 2 consultas, mas se você não tiver um índice sobre o que você coloca na cláusula where (id no seu caso), usar SQL_CALC_FOUND_ROWS é mais eficiente.
fonte
IMHO, a razão pela qual 2 consultas
são mais rápidos do que usar SQL_CALC_FOUND_ROWS
tem que ser visto como um caso particular.
De fato, depende da seletividade da cláusula WHERE comparada à seletividade da implícita equivalente à ORDER + LIMIT.
Como Arvids disse no comentário ( http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/#comment-1174394 ), o fato de o EXPLAIN usar ou não, tabela temporária, deve ser uma boa base para saber se o SCFR será mais rápido ou não.
Mas, como eu adicionei ( http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/#comment-8166482 ), o resultado realmente depende do caso. Para um paginador específico, você pode concluir que “nas 3 primeiras páginas, use 2 consultas; para as páginas seguintes, use um SCFR ”!
fonte
Remover alguns SQL desnecessários e depois
COUNT(*)
será mais rápido queSQL_CALC_FOUND_ROWS
. Exemplo:Depois conte sem parte desnecessária:
fonte
Existem outras opções para você comparar:
1.) Uma função de janela retornará o tamanho real diretamente (testado no MariaDB):
2.) Pensando fora da caixa, na maioria das vezes os usuários não precisam saber o tamanho EXATO da tabela, uma aproximação geralmente é boa o suficiente.
fonte