sql >> Base de Datos >  >> RDS >> Mysql

mysql:muy simple SELECT id ORDER BY LIMIT no usará INDEX como se esperaba (?!)

Las búsquedas en el índice son por valor , no por posición . Un índice puede buscar un valor 2955900, pero no está pidiendo eso. Está solicitando que la consulta comience en un desplazamiento de la fila 2955900 de la tabla.

El optimizador no puede asumir que todos los valores de clave principal son consecutivos. Por lo tanto, es bastante probable que la fila 2955900 tenga un valor mucho más alto que eso.

Incluso si los valores de la clave principal son consecutivos, es posible que tenga una condición DONDE que solo coincida, por ejemplo, con el 45 % de las filas. En cuyo caso, el valor de identificación en la fila 2955900 sería camino más allá del valor de identificación 2955900.

En otras palabras, una búsqueda en el índice del valor de identificación 2955900 no entregará la fila 2955900.

Entonces MySQL no puede usar el índice para la compensación de un límite. debe escanee las filas para contarlas hasta que llegue a la compensación+límite de filas.

MySQL tiene optimizaciones relacionadas con LIMIT , pero se trata más de detener un escaneo de tabla una vez que ha alcanzado el número de filas para devolver. El optimizador aún puede informar en un plan EXPLAIN que espera que podría tienes que escanear toda la tabla.

Un malentendido frecuente sobre FORCE INDEX es que fuerza el uso de un índice. :-)De hecho, si la consulta no puede usa un índice (o si los índices disponibles no tienen ningún beneficio para esta consulta), FORCE INDEX no tiene efecto.

Re tu comentario:

La paginación es una pesadilla frecuente de las aplicaciones web basadas en datos. A pesar de lo común que es esta característica, no es fácil de optimizar. Estos son algunos consejos:

  • ¿Por qué está consultando con el desplazamiento 2955900? ¿Realmente espera que los usuarios revisen tantas páginas? La mayoría de los usuarios se dan por vencidos después de algunas páginas (la cantidad exacta depende del tipo de aplicación y los datos).

  • Reducir el número de consultas. Su función de paginación podría obtener las primeras 5-10 páginas, incluso si solo muestra la primera página al usuario. Guarde en caché las otras páginas, asumiendo que el usuario avanzará a través de algunas páginas. Solo si avanzan más allá del conjunto de páginas en caché, su aplicación tiene que hacer otra consulta. Incluso podría almacenar en caché las 10 páginas en Javascript en el navegador del cliente, por lo que hacer clic en "Siguiente" es instantánea para ellos (al menos para esas primeras páginas).

  • No coloque un botón "Último" en ninguna interfaz de usuario, porque la gente hará clic en él por curiosidad. Observe que Google tiene un botón "Siguiente" pero no un botón "Último". Por lo tanto, la propia interfaz de usuario disuade a las personas de ejecutar consultas ineficientes con compensaciones altas.

  • Si el usuario avanza una página a la vez, use el valor de identificación más alto devuelto en la página anterior en la cláusula WHERE de la consulta de la página siguiente. Es decir. lo siguiente hace use el índice, incluso sin la sugerencia FORCE INDEX:

    SELECT * FROM thistable WHERE id > 544 LIMIT 20