Conceptos básicos de la entrevista de PHP | Estrategia y optimización de uso del índice MySQL

La optimización de MySQL se divide principalmente en optimización de estructura (optimización de esquema) y optimización de consulta (optimización de consulta).

Las estrategias de indexación de alto rendimiento discutidas en este artículo pertenecen principalmente a la categoría de optimización estructural. El contenido de este artículo se basa completamente en la base teórica anterior. De hecho, una vez que comprende el mecanismo detrás del índice, elegir una estrategia de alto rendimiento se convierte en un razonamiento puro y puede comprender la lógica detrás de estas estrategias.

Uno, la base de datos de muestra

Para discutir la estrategia de indexación, se necesita como ejemplo una base de datos con una pequeña cantidad de datos. Este artículo utiliza una de las bases de datos de muestra que se proporcionan en la documentación oficial de MySQL: empleados. Esta base de datos tiene una complejidad moderada y una gran cantidad de datos. La siguiente figura es el diagrama ER de esta base de datos (citado del manual oficial de MySQL):

Inserte la descripción de la imagen aquí

2. El principio del prefijo más a la izquierda y la optimización relacionada

La primera condición para el uso eficiente de índices es saber qué tipo de consulta usará el índice. Este problema está relacionado con el "principio del prefijo más a la izquierda" en B + Tree. El siguiente ejemplo ilustra el principio del prefijo más a la izquierda.

Permítanme hablar primero sobre el concepto de índice conjunto. En lo anterior, todos asumimos que el índice solo se refiere a una sola columna. De hecho, un índice en MySQL puede referirse a múltiples columnas en un orden determinado. Este tipo de índice se llama índice conjunto.

Generalmente, un índice conjunto es una tupla ordenada <a1, a2, ..., an>, donde cada elemento es una columna de la tabla de datos. De hecho, para definir estrictamente el índice se requiere el uso de álgebra relacional, pero no quiero discutir demasiado aquí. El tema del álgebra multirrelacional, porque sería muy aburrido, por lo que no hay una definición estricta aquí. Además, un índice de una sola columna puede considerarse un caso especial en el que el número de elementos en un índice conjunto es 1.

Tome la tabla employee.titles como ejemplo, primero verifiquemos qué índices están en ella:

Inserte la descripción de la imagen aquí

Tres, EXPLICAR

En nuestro trabajo diario, a veces abrimos consultas lentas para registrar algunas declaraciones SQL que se han ejecutado durante mucho tiempo. Descubrir estas declaraciones SQL no significa que hayamos terminado. A veces, a menudo usamos el comando explicar para ver una de estas declaraciones SQL. El plan de ejecución de la declaración SQL, verifique si la declaración SQL usa el índice, si se debe hacer un escaneo completo de la tabla, esto se puede verificar mediante el comando explicar

Entonces, tenemos un conocimiento profundo del optimizador basado en costos de MySQL, y también podemos obtener muchos detalles sobre la estrategia de acceso que puede ser considerada por el optimizador, y qué estrategia se espera que adopte el optimizador al ejecutar declaraciones SQL.

La información de EXPLAIN tiene 10 columnas, a saber, id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra

Descripción resumida:

  • id: seleccione identificador
  • select_type: indica el tipo de consulta.
  • tabla: la tabla del conjunto de resultados de salida
  • tipo: indica el tipo de conexión de la tabla

todo (escaneo de tabla completo), índice (escaneo de tabla completo según el orden del índice), rango (escaneo de índice de rango)
req (la columna de condición de búsqueda usa el índice y no es la clave principal y única, el valor de la columna de índice no es único ), ref_eq (cuando se utiliza la clave principal o el índice único para la búsqueda),
const (la clave principal se coloca después de donde, como consulta condicional, el optimizador de mysql puede optimizar esta consulta en una constante)

  • possible_keys: indica los índices que se pueden utilizar al realizar consultas
  • clave: indica el índice real utilizado
  • key_len: la longitud del campo de índice
  • ref: comparación de columnas e índices
  • filas: el número de filas escaneadas (número estimado de filas)
  • Extra: descripción y explicación de la implementación

Cuatro, contenido específico

Caso 1: Coincidencia de columna completa

Inserte la descripción de la imagen aquí

explain SELECT * FROM employees.titles WHERE emp_no='10001' AND title = 'Senior Engineer' AND from_date='1986-06-26';

Obviamente, el índice se puede utilizar cuando se realiza una coincidencia exacta de acuerdo con todas las columnas del índice (aquí la coincidencia exacta se refiere a la coincidencia "=" o "IN"). Una cosa a tener en cuenta aquí es que el índice es teóricamente sensible al orden, pero debido a que el optimizador de consultas de MySQL ajustará automáticamente el orden condicional de la cláusula where para usar un índice adecuado, por ejemplo, invertimos el orden de las condiciones en las que el efecto es el mismo. .

Caso 2: coincide con el prefijo más a la izquierda

Inserte la descripción de la imagen aquí

EXPLAIN SELECT * FROM employees.titles WHERE emp_no='10001';

Cuando la condición de la consulta coincide exactamente con una o varias columnas en el lado izquierdo del índice, como o <emp_no, title>, se puede usar, pero solo una parte, es decir, el prefijo más a la izquierda compuesto por la condición. La consulta anterior usa el índice PRIMARY de los resultados del análisis, pero key_len es 4, lo que indica que solo se usa el prefijo de la primera columna del índice.

Caso 3: la condición de la consulta usa la coincidencia exacta de la columna en el índice, pero no se proporciona una de las condiciones en el medio

Inserte la descripción de la imagen aquí

EXPLAIN SELECT * FROM employees.titles WHERE emp_no='10001' AND from_date='1986-0626';

En este momento, el uso del índice es el mismo que en el caso dos, porque no se proporciona el título, por lo que la consulta solo usa la primera columna del índice, y la última desde_fecha también está en el índice, pero no puede conectarse con el prefijo izquierdo porque el título no existe, por lo que necesita Escanee y filtre los resultados from_date (aquí, porque emp_no es único, no hay escaneo).

Si desea que from_date también use un índice en lugar de dónde filtrar, puede agregar un índice auxiliar <emp_no, from_date>, y la consulta anterior usará este índice. Además, también puede utilizar un método de optimización llamado "columna de aislamiento" para completar el "pozo" entre emp_no y from_date.

Primero, veamos el título. Hay varios valores diferentes:

Estrategia y optimización de uso de índices de MySQL

Solo hay 7 tipos. En este caso, donde hay menos valores de columna llamados "hoyos", puede considerar usar "IN" para llenar los "hoyos" para formar el prefijo más a la izquierda:

Inserte la descripción de la imagen aquí

Esta vez key_len es 56, lo que indica que el índice está agotado, pero a partir del tipo y las filas podemos ver que IN realmente ejecutó una consulta de rango, aquí se verifican 7 claves.

El rendimiento mejoró un poco después de "llenar el agujero". Si quedan muchos datos después del filtrado emp_no, la ventaja de rendimiento de este último será más obvia. Por supuesto, si el valor del título es demasiado, no es apropiado llenar el vacío y se debe establecer un índice auxiliar.

Situación 4: la condición de consulta no especifica la primera columna del índice

Inserte la descripción de la imagen aquí

Dado que no es el prefijo más a la izquierda, el índice obviamente no se utiliza para consultas como índices.

Situación cinco: haga coincidir la cadena de prefijo de una columna

Inserte la descripción de la imagen aquí

El índice se puede usar en este momento, pero si el comodín no solo aparece al final, no se puede usar el índice. (El texto original es incorrecto. Si el comodín% no aparece al principio, se puede usar el índice, pero dependiendo de la situación, solo se puede usar uno de los prefijos)

Situación seis: consulta de rango

Inserte la descripción de la imagen aquí

La columna de rango puede usar el índice (debe ser el prefijo más a la izquierda), pero la columna después de la columna de rango no puede usar el índice. Al mismo tiempo, el índice se usa como máximo para una columna de rango, por lo que si hay dos columnas de rango en la condición de consulta, el índice no se puede usar en su totalidad.

Inserte la descripción de la imagen aquí

Puede ver que el índice no puede hacer nada con el índice del segundo rango. Aquí hay un punto especial para explicar MySQL, es decir, es posible que solo el uso de explicar no pueda distinguir entre el índice de rango y la coincidencia de valores múltiples, porque ambos se muestran como rango de tipo. Al mismo tiempo, usar "entre" no significa una consulta de rango, como la siguiente consulta:

Inserte la descripción de la imagen aquí

Parece que se utilizan dos consultas de rango, pero "BETWEEN" que actúa sobre emp_no es en realidad equivalente a "IN", lo que significa que emp_no es en realidad una coincidencia exacta de varios valores. Puede ver que esta consulta usa las tres columnas del índice. Por lo tanto, es necesario distinguir cuidadosamente entre la coincidencia de múltiples valores y la coincidencia de rango en MySQL, de lo contrario, el comportamiento de MySQL se confundirá.

Caso siete, selección de índice e índice de prefijo

Dado que el índice puede acelerar la velocidad de la consulta, ¿debería construirse el índice siempre que la declaración de la consulta lo requiera? la respuesta es negativa. Aunque el índice acelera la consulta, el índice tiene un precio: el archivo de índice en sí mismo consume espacio de almacenamiento y el índice aumentará la carga de insertar, eliminar y modificar registros. Además, MySQL también consume recursos para mantener el índice cuando se está ejecutando. Por tanto, el índice no es mejor. Generalmente, no se recomienda construir un índice en dos casos.

El primer caso es que los registros de la tabla son relativamente pequeños, como una tabla con uno a dos mil o incluso unos pocos cientos de registros. No es necesario crear un índice, simplemente deje que la consulta realice un escaneo completo de la tabla. En cuanto a cuántos registros se cuentan como demasiados, esta persona tiene una opinión personal. Mi experiencia personal se basa en 2000 como línea divisoria. Si el número de registros no supera los 2000, puede considerar no indexar, y si supera los 2000, puede considerar la indexación según corresponda.

Otra situación en la que no se recomienda la indexación es la baja selectividad del índice. La llamada selectividad de índice (selectividad) se refiere a la relación entre el valor de índice único (también llamado cardinalidad) y el número de registros de la tabla (#T):

Index Selectivity = Cardinality / #T

Obviamente, el rango de selectividad es (0, 1], cuanto mayor es la selectividad, mayor es el valor del índice, que está determinado por la naturaleza del árbol B +. Por ejemplo, la tabla empleados.títulos utilizada anteriormente, si el campo de título A menudo se consulta por separado, si es necesario construir un índice, echemos un vistazo a su selectividad:

Inserte la descripción de la imagen aquí

La selectividad del título es inferior a 0,0001 (el valor exacto es 0,00001579), por lo que realmente no es necesario crear un índice separado para él.

Existe una estrategia de optimización de índice relacionada con la selectividad del índice denominada índice de prefijo, que utiliza el prefijo de la columna en lugar de toda la columna como clave de índice. Cuando la longitud del prefijo es adecuada, la selectividad del índice de prefijo puede ser cercana a la del índice de columna completa. La clave de índice se acorta, lo que reduce el tamaño del archivo de índice y la sobrecarga de mantenimiento. A continuación, se toma la tabla empleados.empleados como ejemplo para presentar la selección y el uso de índices de prefijo.

En el diagrama de la base de datos de muestra, podemos ver que la tabla de empleados tiene solo un índice. Si queremos buscar a una persona por su nombre, solo podemos escanear toda la tabla. Si buscamos empleados con frecuencia por su nombre, obviamente esto es muy ineficiente, por lo que podemos considerar construir un índice. . Hay dos opciones, build o <first_name, last_name>, observe la selectividad de los dos índices:

Inserte la descripción de la imagen aquí

Obviamente, la selectividad es demasiado baja, la selectividad es muy buena, pero la longitud combinada de first_name y last_name es 30, ¿hay alguna manera de equilibrar la longitud y la selectividad? >> Considere usar los primeros caracteres de first_name y last_name para construir un índice, por ejemplo, para ver su selectividad:

Estrategia y optimización de uso de índices de MySQL

En este momento, la selectividad es ideal, y la longitud de este índice es solo 18, que es casi la mitad más corta que eso. Creamos este índice de prefijo: ALTER TABLE employees.employees ADD INDEX `first_name_last_name4 `(first_name, last_name (4));en este momento, realice la consulta por nombre nuevamente y compare y analice los resultados antes del índice: La mejora del rendimiento es significativa y la velocidad de consulta se ha incrementado en más de 120 veces.

El índice de prefijo tiene en cuenta el tamaño del índice y la velocidad de la consulta, pero su desventaja es que no se puede usar para las operaciones ORDER BY y GROUP BY, ni para cubrir el índice (es decir, cuando el índice en sí contiene todos los datos necesarios para la consulta, ya no se accede al archivo de datos).

Presta atención, no te pierdas

Muy bien, todos, lo anterior es todo el contenido de este artículo. Las personas que pueden ver aquí son todos talentos . Como dije antes, hay muchos puntos técnicos en PHP, porque hay demasiados, es realmente imposible de escribir, y no leerás demasiado después de escribirlo, así que lo organizaré en PDF y documentos aquí, si es necesario. lata

Haga clic para ingresar el código secreto: PHP + 「Plataforma」

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí


Para obtener más contenido de aprendizaje, visite el excelente catálogo de tutoriales de arquitecto PHP de [Comparative Standard Factory], siempre que pueda leerlo para asegurarse de que el salario aumentará un paso (actualización continua)

El contenido anterior espera poder ayudarte . Muchos PHPers siempre encuentran algunos problemas y cuellos de botella cuando están avanzados. No hay sentido de dirección cuando escriben demasiado código comercial. No sé por dónde empezar a mejorar. He compilado información sobre esto, incluyendo Pero no se limita a: arquitectura distribuida, alta escalabilidad, alto rendimiento, alta concurrencia, ajuste del rendimiento del servidor, TP6, laravel, YII2, Redis, Swoole, Swoft, Kafka, optimización de Mysql, scripts de shell, Docker, microservicios, Nginx, etc. Muchos puntos de conocimiento, productos secos avanzados avanzados, se pueden compartir con todos de forma gratuita, y aquellos que lo necesiten pueden unirse a mi grupo de intercambio de tecnología PHP

Supongo que te gusta

Origin blog.csdn.net/weixin_49163826/article/details/108760331
Recomendado
Clasificación