Esquema de optimización de consultas de paginación MySQL para grandes volúmenes de datos

Método 1: use la instrucción SQL proporcionada por la base de datos directamente

Estilo de declaración: en  MySQL, están disponibles los siguientes métodos:

SELECT * FROM 表名称 LIMIT M,N

Adaptarse a la escena:  adecuado para situaciones con una pequeña cantidad de datos (tupla cientos / miles)

Razones / desventajas:  escaneo completo de la tabla, la velocidad será muy lenta y algunos conjuntos de resultados de la base de datos devuelven inestables (como devolver 1, 2, 3 a la vez y devolver 2, 1, 3 en el otro momento). El límite está limitado por el conjunto de resultados Saque la salida de N en la posición M y descarte el resto.

 

Método 2: cree una clave principal o un índice único, use el índice (asumiendo 10 entradas por página)

Estilo de declaración: en  MySQL, están disponibles los siguientes métodos:

SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) LIMIT M

Escenarios de adaptación:  adecuados para situaciones con una gran cantidad de datos (decenas de miles de tuplas)

Motivo:  escaneo de índice, la velocidad será muy rápida. Un amigo sugirió: debido a que la consulta de datos no está ordenada de acuerdo con pk_id, habrá casos en los que falten datos, solo el método 3

 

Método 3: reordenar según el índice

Estilo de declaración: en  MySQL, están disponibles los siguientes métodos:

SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) ORDER BY id_pk ASC LIMIT M

Escenarios de adaptación:  Adecuado para situaciones con una gran cantidad de datos (decenas de miles de tuplas). Es mejor que el objeto de columna después de ORDER BY sea la clave principal o única, de modo que la operación ORDERBY pueda ser eliminada por el índice pero el conjunto de resultados sea estable (significado estable , Ver método 1)

Razón: el  escaneo de índices será muy rápido, pero la operación de clasificación de MySQL es solo ASC sin DESC (DESC es falso, el DESC real se realizará en el futuro, esperamos ...).

 

Método 4: use prepare basado en el índice

El primer signo de interrogación significa pageNum, ¿el segundo? Indica el número de tuplas por página.

Estilo de declaración: en  MySQL, están disponibles los siguientes métodos:

PREPARE stmt_name FROM SELECT * FROM 表名称 WHERE id_pk > (?* ?) ORDER BY id_pk ASC LIMIT M

Adaptarse a la escena:  gran volumen de datos

Motivo:  escaneo de índice, la velocidad será muy rápida La instrucción de preparación es un poco más rápida que la instrucción de consulta general.

 

Método 5: el uso de MySQL para admitir operaciones ORDER puede usar índices para ubicar rápidamente algunas tuplas y evitar escaneos completos de tablas

Por ejemplo: lea la tupla de fila 1000 a 1019 (pk es la clave principal / clave única).

SELECT * FROM your_table WHERE pk>=1000 ORDER BY pk ASC LIMIT 0,20

Método 6: use "subconsulta / join + index" para localizar rápidamente la posición de la tupla y luego lea la tupla.

Por ejemplo (id es la clave principal / clave única, variable en fuente azul)

Ejemplos de uso de subconsultas:

SELECT * FROM your_table WHERE id <=
(SELECT id FROM your_table ORDER BY id desc LIMIT ($page-1)*$pagesize ORDER BY id desc
LIMIT $pagesize 

Utilice el ejemplo de conexión:

SELECT * FROM your_table AS t1
JOIN (SELECT id FROM your_table ORDER BY id desc LIMIT ($page-1)*$pagesize AS t2
WHERE t1.id <= t2.id ORDER BY t1.id desc LIMIT $pagesize; 

MySQL utiliza la paginación límite para grandes volúmenes de datos. A medida que aumenta el número de página, la eficiencia de la consulta se reduce.

 

Experimento de prueba

1. Usar directamente las declaraciones de paginación de inicio de límite y conteo, que también son los métodos utilizados en mi programa:

select * from product limit start, count 

Cuando la página de inicio es pequeña, la consulta no tiene problemas de rendimiento. Veamos el tiempo de ejecución de paginación desde 10, 100, 1000, 10000 (20 entradas por página).

como sigue:

select * from product limit 10, 20   --0.016秒 
select * from product limit 100, 20  -- 0.016秒
select * from product limit 1000, 20  -- 0.047秒
select * from product limit 10000, 20   --0.094秒

Hemos visto que a medida que aumenta el registro inicial, el tiempo también aumenta. Esto muestra que el límite de la declaración de paginación tiene mucho que ver con el número de página inicial. Luego cambiamos el registro inicial a 40w y lo miramos (es decir, el registro En general)

select * from product limit 400000, 20   --3.229秒 

Mira el momento en que tomamos la última página de registros

select * from product limit 866613, 20   --37.44秒 

Obviamente este tipo de tiempo es insoportable para la página de mayor número de página de este tipo de paginación.

De esto también podemos resumir dos cosas:

  • El tiempo de consulta de la declaración de límite es proporcional a la posición del registro inicial

  • La declaración de límite de mysql es muy conveniente, pero no es adecuada para uso directo en tablas con muchos registros.

 

2. Método de optimización del rendimiento para problemas de paginación límite

Utilice el índice de cobertura de la tabla para acelerar las consultas de paginación

Todos sabemos que si solo se incluye la columna de índice (índice de cobertura) en la declaración que usa la consulta de índice, la consulta será muy rápida en este caso.

Debido a que existe un algoritmo optimizado para la búsqueda de índices y los datos están en el índice de la consulta, no es necesario encontrar la dirección de datos relevante, lo que ahorra mucho tiempo. Además, hay cachés de índice relacionados en Mysql. Es mejor usar el caché cuando la concurrencia es alta.

En nuestro ejemplo, sabemos que el campo id es la clave principal, por lo que naturalmente contiene el índice de clave principal predeterminado. Ahora veamos el efecto de la consulta usando el índice de cobertura.

Esta vez consultamos los datos de la última página (usando el índice de cobertura, que solo contiene la columna id), de la siguiente manera:

select id from product limit 866613, 20 0.2秒 

En comparación con 37,44 segundos para consultar todas las columnas, es aproximadamente 100 veces más rápido

Entonces, si queremos consultar todas las columnas, hay dos métodos, uno tiene la forma id> = y el otro es usar join. Mira la situación real:

SELECT * FROM product WHERE ID > =(select id from product limit 866613, 1) limit 20

¡El tiempo de consulta es de 0,2 segundos!

 

Otra forma de escribir

SELECT * FROM product a JOIN (select id from product limit 866613, 20) b ON a.ID = b.id

¡El tiempo de consulta también es muy corto!

3. Método de optimización del índice compuesto

¿Qué tan alto puede ser el rendimiento de MySql? MySql es definitivamente una base de datos adecuada para que jueguen los maestros de nivel dba. Generalmente, puede escribir un sistema pequeño con 10,000 artículos de noticias. Se puede lograr un desarrollo rápido con el marco xx.

Pero la cantidad de datos ha llegado a 100.000, de millones a decenas de millones, ¿puede su rendimiento ser tan alto? Un pequeño error puede hacer que se reescriba todo el sistema, ¡o incluso que el sistema no pueda funcionar normalmente! Está bien, no tanto tonterías.

 

Habla con hechos, mira ejemplos:

La recopilación de la tabla de datos (id, title, info, vtype) tiene estos 4 campos, donde el título usa una longitud fija, la información usa texto, la identificación es gradual, vtype es tinyint y vtype es index.

Este es un modelo simple de un sistema de noticias básico. Ahora complete los datos para completar 100,000 noticias. Finalmente, recolectar es 100,000 registros, y la tabla de la base de datos ocupa 1.6G.

Bien, mira la siguiente declaración SQL:

select id,title from collect limit 1000,10;

Pronto; básicamente está bien en 0.01 segundos, luego mira lo siguiente

select id,title from collect limit 90000,10;

La paginación comienza desde 90.000, ¿el resultado?

8-9 segundos para completar, ¿qué le pasa a mi dios? De hecho, para optimizar estos datos, encuentre la respuesta en línea. Mira la siguiente declaración:

select id from collect order by id limit 90000,10;

Pronto, 0,04 segundos estarán bien. ¿por qué? Debido a que la clave principal de id se usa para indexar, por supuesto que es rápido.

La reforma online es:

select id,title from collect where id>=(select id from collect order by id limit 90000,1) limit 10;

Este es el resultado de indexar con id. Pero si el problema es un poco complicado, se acabó. Mira la siguiente declaración

select id from collect where vtype=1 order by id limit 90000,10; 

Muy lento, ¡tomó de 8 a 9 segundos!

¡Cuando llegue aquí, creo que mucha gente se sentirá rota! ¿Vtype está indexado? ¿Cómo puede ser lento? vtype index es bueno, directamente

select id from collect where vtype=1 limit 1000,10;

Es muy rápido, básicamente 0.05 segundos, pero se incrementa en 90. A partir de 90.000, esa es la velocidad de 0.05 * 90 = 4.5 segundos. Y el resultado de la prueba alcanzó un orden de magnitud en 8-9 segundos.

 

A partir de aquí, alguien propuso la idea de submesa, esta es la misma idea que dis #cuz forum. La idea es la siguiente:

Cree una tabla de índice: t (id, title, vtype) y configúrela a una longitud fija, luego realice la paginación, y luego los resultados se paginarán para encontrar información en recopilar. Es factible Bajo el experimento lo sabrás.

Se almacenan 100.000 registros en t (id, title, vtype) y el tamaño de la tabla de datos es de unos 20M. utilizar

select id from t where vtype=1 order by id limit 90000,10;

pronto. Básicamente, puede ejecutarse en 0,1-0,2 segundos. ¿Por qué esto es tan?

Supongo que se debe a que los datos recopilados son demasiados, por lo que la paginación será de gran ayuda. El límite está completamente relacionado con el tamaño de la tabla de datos. De hecho, este sigue siendo un escaneo de tabla completo, solo porque la cantidad de datos es pequeña, solo 100,000 es rápido. Bien, hagamos un experimento loco, agregue 1 millón para probar el rendimiento. Después de agregar 10 veces los datos, la tabla t alcanzó inmediatamente más de 200M y tenía una longitud fija. Aún así, la declaración de consulta hace un momento, ¡el tiempo es de 0.1-0.2 segundos para completar! ¿No hay problema con el rendimiento por debajo del metro?

¡incorrecto! Porque nuestro límite sigue siendo de 90.000, muy rápido. Regala uno grande, empieza en 900.000

select id from t where vtype=1 order by id limit 900000,10;

Mira el resultado, ¡el tiempo es de 1-2 segundos! ¿por qué?

Todavía queda tanto tiempo después de la submesa, ¡muy deprimente! Algunas personas dicen que la longitud fija mejorará el rendimiento del límite. Al principio pensé que debido a que la longitud de un registro es fija, mysql debería poder calcular la posición de 900.000, ¿verdad? Pero sobrestimamos la inteligencia de mysql. No es una base de datos comercial. ¿Resulta que la longitud fija y la longitud no fija tienen poco efecto sobre el límite? No es de extrañar que algunas personas digan que discuz será muy lento después de alcanzar 1 millón de registros. Creo que esto es cierto. ¡Esto está relacionado con el diseño de bases de datos!

¿No puede MySQL romper el límite de 1 millón? ? ? ¿Es realmente el límite cuando llega a 1 millón de páginas?

La respuesta es: ¿Por qué NO puede exceder 1 millón? Se debe a que no se diseñó mysql. Vamos a presentar el método de la tabla sin división, ¡hagamos una prueba loca! Una tabla maneja 1 millón de registros y una base de datos de 10G, ¡cómo paginar rápidamente!

De acuerdo, nuestra prueba regresa a la tabla de recopilación y la conclusión de la prueba es:

300.000 datos, es factible utilizar el método de subtabla, ¡y la velocidad de más de 300.000 será demasiado lenta para que la soporte! Por supuesto, si usa el método sub-table + me, es absolutamente perfecto. Pero después de usar mi método, ¡se puede resolver perfectamente sin subtabla!

La respuesta es: índice compuesto. Una vez, al diseñar un índice mysql, descubrí accidentalmente que el nombre del índice se puede elegir a voluntad y se pueden seleccionar varios campos.

El principio

select id from collect order by id limit 90000,10; 

Es muy rápido porque el índice se ha ido, pero si agrega dónde, no se tomará el índice. Agregué un índice como search (vtype, id) con la idea de intentarlo.

Entonces prueba

select id from collect where vtype=1 limit 90000,10; 

¡muy rapido! ¡Completado en 0.04 segundos!

Prueba de nuevo:

select id ,title from collect where vtype=1 limit 90000,10; 

Desafortunadamente, 8-9 segundos, ¡sin índice de búsqueda!

Prueba de nuevo: busca (id, vtype), o selecciona id en esta frase, también muy lamentable, 0,5 segundos.

En resumen: si tiene condiciones where y desea usar el límite para el índice, debe diseñar un índice. Coloque dónde primero y la clave principal utilizada por límite en segundo lugar, ¡y solo puede seleccionar la clave principal!

El problema de la paginación se resuelve perfectamente. Si puede devolver la identificación rápidamente, existe la esperanza de optimizar el límite. De acuerdo con esta lógica, un límite de un millón de niveles debe dividirse en 0.0x segundos. ¡Parece que la optimización y la indexación de las declaraciones de mysql son muy importantes!

 

Supongo que te gusta

Origin blog.csdn.net/bj_chengrong/article/details/103233267
Recomendado
Clasificación