Não entendi ao consultar 5 linhas de uma tabela de 500.000 linhas, a seguinte consulta leva 0,00seg:
SELECT id, username FROM Users FORCE INDEX (PRIMARY) ORDER BY id LIMIT 20,5;
Mas consultar exatamente as mesmas linhas no sentido inverso leva 2,50 segundos:
SELECT id, username FROM Users FORCE INDEX (PRIMARY) ORDER BY id DESC LIMIT 499975,5;
Além disso, se eu não forçar o índice para a segunda consulta, o MySQL optará por não usá-lo.
Observo que há um plano para introduzir ordem de classificação para o índice, mas isso não explica por que o MySQL não pode usar o mesmo índice de forma eficaz quando LIMIT offset é grande, pois conhece a contagem total de linhas.
Sim, o grande deslocamento é um problema. O MySQL faz pesquisas de linha iniciais, que não permitem descartar dados tão facilmente quanto se imagina. O MySQL recupera todos os registros enquanto processa o banco de dados e cada registro pode ter comprimento variável. Jogar as linhas fora depois se torna tão complicado quanto jogar fora cada linha. Não é como "jogar fora
x*y bytes
".Existem truques para forçar o MySQL na pesquisa de linha tardia, o que significa processar o índice e fazer todas as operações relacionadas a isso, além de recuperar a linha. Isso oferece a possibilidade de descartar linhas muito mais rapidamente.
Ver
É provavelmente porque a varredura reversa de um índice pode ser mais lenta que a varredura direta, conforme explicado, por exemplo, aqui: http://www.mysqlperformanceblog.com/2006/05/09/descending-indexing-and-loose-index- Varredura/