Con compensaciones grandes, MySQL
necesita buscar más registros.
Incluso si el plan utiliza filesort
(lo que significa que todos los registros se deberían explorar), MySQL
lo optimiza para que sólo $offset + $limit
registros superiores están ordenados, lo que hace que sea mucho más eficiente para los valores más bajos de $offset
.
La solución típica es indexar las columnas que está ordenando en, grabar el último valor de las columnas y reutilizarla en las consultas posteriores, así:
SELECT *
FROM mytable
ORDER BY
value, id
LIMIT 0, 10
que emite:
value id
1 234
3 57
4 186
5 457
6 367
8 681
10 366
13 26
15 765
17 345 -- this is the last one
para acceder a la página siguiente, se debería utilizar:
SELECT *
FROM mytable
WHERE (value, id) > (17, 345)
ORDER BY
value, id
LIMIT 0, 10
, que utiliza el en dex en (value, id)
.
Por supuesto, esto no ayudará con las páginas de acceso arbitrario, pero ayuda con la exploración secuencial.
Además, MySQL
tiene ciertos problemas con la búsqueda tardía de filas. Si se indexan las columnas, puede valer la pena tratar de reescribir su consulta como esta:
SELECT *
FROM (
SELECT id
FROM mytable
ORDER BY
value, id
LIMIT $offset, $limit
) q
JOIN mytable m
ON m.id = q.id
Consulte este artículo para obtener una explicación más detallada:
Buena pregunta, yo soy no está familiarizado con el funcionamiento de MySQL en este sentido. – RedFilter
Gracias por las respuestas, lo probaremos más tarde con la esperanza de ganar algo de velocidad. – Omiod