Ajuste del índice mysql

1. Ajuste del índice de mysql

1.1 Explicación

Antes de la explicación de la optimización, recuerde no escuchar la "verdad absoluta" que ve sobre la optimización, sino verificar sus suposiciones sobre el plan de ejecución y el tiempo de respuesta a través de pruebas en escenarios comerciales reales.

1.2 Dirección de optimización

Inserte la descripción de la imagen aquí

Como se puede ver en la figura anterior, dividimos la optimización de la base de datos en cuatro latitudes: hardware, configuración del sistema, estructura de la tabla de la base de datos, SQL e índice.

** Hardware: ** CPU, memoria, almacenamiento, equipo de red, etc.

Configuración del sistema: sistema del servidor, parámetros del servicio de la base de datos, etc.

Estructura de la tabla de la base de datos: alta disponibilidad, subtabla de la subbase de datos, separación de lectura y escritura, motor de almacenamiento, diseño de la tabla, etc.

SQL e índice: declaración SQL, uso del índice, etc.

  • Considere del costo de optimización: hardware> configuración del sistema> estructura de la tabla de la base de datos> SQL e índice
  • Considere el efecto de optimización: hardware <configuración del sistema <estructura de la tabla de la base de datos <SQL e índice

Este artículo explicará el SQL y los índices con el menor costo de optimización y el mejor efecto.

1.3 Página de datos

B + Tree es un árbol para encontrar un diseño deficiente del dispositivo de almacenamiento en disco de equilibrio, el motor de almacenamiento InnoDB es un B + Tree logra su estructura de índice

Antes de comprender la estructura del árbol B + , primero comprenda estos dos conceptos

** Disco: ** El sistema lee los datos del disco a la memoria basándose en el bloque de disco (bloque), y los datos ubicados en el mismo bloque de disco se leerán al mismo tiempo.

Página de datos: InnoDB está usando una página como la unidad básica de gestión del espacio de almacenamiento, InnoDB cuando los datos se leen en el disco de memoria es la unidad básica de una página, el motor de almacenamiento InnoDB el tamaño predeterminado de cada página es 16KB, se puede modificar para 4K, 8K, 16K.

1.3.1 Estructura de la página de datos

Se crea una nueva página de datos, para el proceso de inserción de datos.

Inserte la descripción de la imagen aquí

Cuando Free Spacese agoten todos, si hay nuevos registros insertados, solicite una nueva página.

** Registros de usuario: ** La estructura de un registro se muestra en la figura

Inserte la descripción de la imagen aquí

nombre Tamaño (bit) descripción
预留位 1 No lo uses todavía
delete_mask 1 Marque si se borra el registro
min_rec_mask 1 El registro más pequeño en cada nodo no hoja del árbol B + agregará esta marca
n_owned 4 Indica el número de registros que posee el registro actual
heap_no 13 Indica la información de ubicación actualmente registrada en la pila de grabación
record_type 3 Representa el tipo de registro actual, 0representa un registro normal, 1representa un registro de nodo no hoja de árbol B +, 2representa el registro más pequeño, 3representa el registro más grande
next_record dieciséis Indica la posición relativa del siguiente registro

Page Directory: es un directorio para administrar múltiples registros de usuario

  1. Agrupar todos los registros normales (el registro con el valor de clave Infimum más pequeño y el registro con el valor de clave Supermum más grande)
  2. En la información del encabezado del último registro de cada grupo (el registro con el valor de clave más grande del grupo), hay varios registros en el grupo al que pertenece el registro n_owned
  3. El desplazamiento de dirección del último registro de cada grupo se almacena en un directorio en orden, este directorio es Directorio de página y estos desplazamientos de dirección en el directorio se denominan ( ranura )

El diagrama de estructura de Infimum + Supermum + User Records + Page Directory es el siguiente

Inserte la descripción de la imagen aquí

Utilice los datos de la figura anterior para simular el proceso de búsqueda de datos en una página de datos: (búsqueda binaria de ranura y luego atravesar el par de ranuras)

  1. Calcule la posición de la ranura del medio: (0 + 3) / 2 = 1, compruebe que el valor de la clave principal correspondiente a la ranura 1 sea 4, porque la clave principal 4 es más pequeña que la clave principal 6.

    Establecer bajo = 1, alto = 3 sin cambios;

  2. Vuelva a calcular la posición de la ranura del medio: (1 + 3) / 2 = 2, compruebe que el valor correspondiente de la ranura 2 es 8, porque la clave principal 8 es mayor que la clave principal 6

    bajo = 1 sin cambios, ajuste alto = 2

  3. Debido a que alto-bajo = 1, determine el registro de la clave primaria 6 y luego la posición de la ranura2. Encuentre la clave principal 4 más grande del grupo a través de slot1, el next_recode de este registro registra el desplazamiento de dirección del valor 5 de clave principal de slot2, atraviesa el grupo correspondiente a slot2 y busque el registro de la clave principal 6.

1.4 Estructura de datos del árbol B +

Cada página de datos puede estar compuesta por uno 双向链表, y los registros en 单向链表cada página de datos se formarán en el orden de valor de clave primaria de pequeño a grande , y cada página de datos generará uno para los registros almacenados en ella 页目录(Page Directory), y buscará un cierto valor a través de la clave primaria. Cuando hay un registro, puede 页目录utilizar la dicotomía para localizar rápidamente la ranura correspondiente, y luego atravesar los registros en el grupo correspondiente de la ranura para encontrar rápidamente el registro especificado.

Mapa de croquis:

Inserte la descripción de la imagen aquí

1.4.1 Búsqueda sin índice
  • Usando la clave principal como condición de búsqueda, asumiendo que está buscando datos con un registro de 2, en una página de datos, puede usar la dicotomía en el Directorio de páginas para ubicar rápidamente el espacio correspondiente y luego recorrer los registros en el grupo correspondiente de la ranura para encontrar rápidamente el registro especificado. Pero si hay 1000 páginas de datos, y si desea encontrar 10000 en la página 500, tendrá que cargar 500 IO de la página 0 a la 500 para obtener los datos. (Solución: índice principal )
  • Utilice la clave no principal como condición de búsqueda, porque no existe el llamado Directorio de páginas para las columnas de clave no principal en la página de datos , por lo que no podemos localizar rápidamente la dicotomía correspondiente . En este caso, solo puede 最小记录recorrer cada registro en la lista enlazada individualmente desde el principio y luego comparar si cada registro cumple con los criterios de búsqueda. Evidentemente, la eficacia de esta búsqueda es muy baja. (Solución: índice auxiliar )
1.4.2 Índice principal

Inserte la descripción de la imagen aquí

** Índice principal: ** El valor de la clave es la identificación de la clave principal, los datos son una fila de datos

例 sql : seleccione * de la tabla donde id = 20 ;

Proceso de búsqueda:

1) Lea la página 0 del nodo raíz, cargue los datos del disco en la memoria, busque la ranura y recorra el grupo de acuerdo con la división binaria. Encuentre p1.

2) Lea la página 1, cárguela en la memoria, busque p5 de acuerdo con la ranura de búsqueda binaria y el grupo transversal.

  1. Lea la página 5, cárguela en la memoria, busque el registro con la clave = 20 de acuerdo con la ranura de búsqueda binaria y el grupo transversal.

El motor de almacenamiento InnoDB de MySQL está diseñado para que resida el nodo raíz en la memoria. Para un árbol b + con una altura de 3, significa que solo se requieren 1 ~ 3 operaciones de E / S de disco para encontrar el registro de fila de una determinada clave valor.

2. Una página de datos tiene un valor predeterminado de 16 KB, el tipo de clave principal de la tabla general es INT (ocupa 4 bytes) o BIGINT (ocupa 8 bytes), el tipo de puntero también es generalmente de 4 u 8 bytes, es decir, una página. (Un nodo en B + Tree) almacena aproximadamente 16B * 1024 / (8B + 8B) = 1024 valores clave.

Índice principal del árbol B + con profundidad 3 : 1024x1024x100 es aproximadamente igual a 100 millones de datos

Índice auxiliar del árbol B + con una profundidad de 3 : 1024x1024x1024 es aproximadamente igual a mil millones de datos

1.4.3 Índice auxiliar

Inserte la descripción de la imagen aquí

** Índice auxiliar: ** El valor de la clave es un campo de clave no principal y los datos son el ID de clave principal de los datos de la fila.

例 sql : seleccione id de la tabla donde key = 4 ;

  1. Lea la página 0 del nodo raíz, cargue los datos del disco en la memoria, busque la ranura y recorra el grupo de acuerdo con la división binaria. Encuentre p1.
  2. Lea la página 1, cárguela en la memoria, busque la ranura y el grupo transversal en el directorio de la página (directorio de la página) mediante la búsqueda binaria, busque p4. Pero dado que el valor de la clave no está restringido de forma única, la clave4 puede existir en varias páginas de datos y porque 1 <4 <20, por lo que los datos específicos se almacenan en p3 y p4
  3. Lea los registros de page3 y page4 en la memoria y busque el registro con key = 4 según la misma regla de búsqueda anterior.

¿Por qué los datos de registro del índice secundario son la identificación de la clave principal?

1. El tamaño de la página de datos es limitado. Cuando los datos son demasiado grandes, la cantidad de valores clave almacenados en una página de datos será pequeña, lo que significa que se debe buscar la misma cantidad de datos y las páginas de datos a cargar son más, y el número de IO es más.

2. Si tiene filas de datos, cada equivalente al establecimiento de un B+árbol necesitará que todos los registros de usuario se copien una y otra vez, una pérdida de espacio de almacenamiento.

1.5 Optimización de MySql en combate real

1.5.1 limitar la optimización de palabras clave

La tabla de usuario existente tiene datos de 500w. Una función es la consulta de paginación más simple, SQL es el siguiente:

seleccione * del usuario donde la edad> 45 limite la página, tamaño;

Cuando la página es más grande, la consulta sql es más lenta, por ejemplo, cuando page = 3000000, size = 10. Este sql ya está en segundos, ¿tiene alguna forma de optimizarlo?

la razón:

  1. Suponga que solo hay un índice de clave principal en la tabla: los datos están en el disco primero, y solo necesito los datos de 3000000 a 3000000 + 10, pero el motor de ejecución no sabe qué registro es el 3000000 de datos. Todo este SQL consultará toda la tabla, emparejará los registros con las condiciones, hasta que se carguen en la memoria los 3000000 + 10 datos que cumplan con las condiciones, y luego descartará el anterior, para luego detener la ejecución.
  2. Suponga que hay un índice de clave primaria y un índice secundario creado por edad en la tabla: los datos están primero en el disco, este sql consultará la identificación de clave primaria según el índice de edad, porque las páginas de datos del árbol b + (nodos) son todos los registros de valores clave ordenados, podemos llegar fácilmente a la posición de la página de datos con edad> 45, y luego cargar 3000000 + 10 piezas de datos de identificación. Debido a que queremos marcar * en lugar de id, todos los datos 3000000 + 10id obtendrán 3000000 + 10 registros basados ​​en el índice de clave principal nuevamente. Luego ejecute la declaración de límite. (PD: podemos ver que la declaración de límite es la última intercepción, que está relacionada con el orden de ejecución de la palabra clave sql, puede entenderlo)

** Dirección de optimización: ** Considere usar índices secundarios para reducir io.

select * from user  u1 right join (select id from user where age > 45 limit 3000000, 10);

Conduzca la declaración de la tabla por separado

select id from user where age > 45 limit 3000000, 10; 

Aunque este sql leerá 3000000 + 10 datos basados ​​en el índice de clave no principal, es decir, el índice creado por edad. En comparación con el sql anterior: sabemos que el nodo hoja de índice de clave no principal puede almacenar más datos que el nodo hoja de índice de clave principal, es decir, cargar los mismos datos, y el índice de clave no principal necesita cargar menos páginas de datos que el índice de clave principal. A continuación, es muy rápido obtener 10 ID y luego consultar la eficiencia en función de la conexión de unión.

1.5.2 en suboptimización clave

La tabla de usuario existente tiene datos de 500w. La tabla tiene tres datos (uid: 1,2,3) de la siguiente manera:

seleccione * del usuario donde se encuentra la identificación (seleccione uid de la tabla1), ¿qué tan eficiente es su ejecución? ¿Tiene alguna manera de optimizarla?

Subjetivamente, pensaremos que ejecutaremos la instrucción en primero, obtendremos tres datos uid (1, 2, 3) y luego realizaremos una consulta de índice de clave primaria en la tabla de usuario. Esto es muy rápido, y también es la consulta método que queremos.

En la versión mysql5.5 : primero explique la declaración de análisis extendido y luego ejecute SHOW WARNINGS; el sql real es el siguiente

SELECT `数据库名`.`user`.`id` AS `id`,`数据库名`.`user `.`name` AS `name`,`数据库名`.`user`.`age` AS `age`
FROM `数据库名`.`user` WHERE <in_optimizer>(`数据库名`.`user`.`id`,<EXISTS>(<primary_index_lookup>(<CACHE>(`数据库名`.`user`.`id`) IN table1 ON PRIMARY)))

En otras palabras, el motor de ejecución optimiza la instrucción in en una instrucción existe. Luego analice este sql: primero realice un escaneo completo de la tabla de usuario, cargue 500w piezas de datos y luego lleve la identificación de la tabla de usuario a la tabla table1 para hacer coincidir. Los datos de 500w en la tabla de usuario dan como resultado coincidencias de 500w para la tabla table1. Este SQL es muy lento en la versión 5.5.

En la versión mysql5.7

同样 先 执行 explique la selección extendida * del usuario donde se encuentra la identificación (seleccione uid de la tabla1) ;

Luego ejecute MOSTRAR ADVERTENCIAS;

Obtenga el sql real de la siguiente manera


Es decir, en la versión 5.7, el motor de ejecución optimiza la instrucción de subconsulta en una conexión de unión. Desde este sql, se puede ver que la tabla en en está optimizada en una tabla de manejo y la tabla externa en está optimizado en una tabla conducida El método de conexión también está en línea con nuestras consultas.

1.5.4 Análisis de búsqueda de alcance

El sql existente es el siguiente

  1. SELECT * FROM t_class WHERE id <= 6, su plan de ejecución?
    Primero recupere el índice de clave principal para obtener el registro del id más bajo = 1, y luego busque el número de registros '2,3,4,5,6,7' a través de una página de datos con una relación de lista enlazada individualmente y devuélvala al servidor, donde la identificación se juzga = 7 no cumple con las condiciones. Termine la búsqueda. Obtenga el conjunto de resultados. \
  2. SELECCIONAR * FROM t_class DONDE id> = 6, ¿su plan de ejecución?
    Primero recupere el registro de identificación con la identificación del índice de clave principal = 6 o mayor que 6 y más cercana a 6. Entonces siento que este disco baja para encontrar todos los discos.

Supongo que te gusta

Origin blog.csdn.net/weixin_44981707/article/details/108506087
Recomendado
Clasificación