MySQL de alto rendimiento en la práctica (3): optimización del rendimiento

34e84bc7db4828560fa10e6d4e31d35d.gif

Este artículo presenta principalmente algunos métodos para optimizar SQL lento. Antes de explicar las medidas de optimización específicas, me gustaría presentar EXPLAIN primero. Es una operación necesaria cuando analizamos la consulta y es más beneficioso comprender el contenido de los resultados de salida. Optimizamos SQL. Para facilitar la lectura de todos, a continuación se especifica que algo como clave1 representa el índice secundario, key_part1 representa la primera parte del índice conjunto, Unique_key1 representa el índice secundario único y Primary_key representa el índice de clave principal. Práctica de MySQL de alto rendimiento (1): estructura de tablas  y práctica de MySQL de alto rendimiento (2): índice son el conocimiento previo de este artículo, todos pueden leerlo.

1. Explique en detalle

Explicar es una declaración de uso común antes de optimizar SQL lento. Puede analizar el plan de consulta específico y nos permite optimizarlo de manera específica. Esta sección es principalmente para que todos comprendan para qué se utiliza cada columna del resultado de la consulta Explicar. Primero echemos un vistazo breve a la función de cada columna:

Lista
describir

identificación

En una declaración de consulta grande, cada palabra clave SELECT corresponde a una identificación única. En una consulta de unión, los valores de identificación de los registros son los mismos; en una consulta con múltiples palabras clave SELECT, el optimizador de consultas puede optimizar la subconsulta para que los valores de identificación de múltiples registros SELECT sean los mismos.

seleccione tipo

Tipo de consulta

mesa

Nombre de la tabla

particiones

Información de partición coincidente

tipo

Método de acceso para una sola mesa.

llaves_posibles

Posibles índices

llave

índice real utilizado

clave_len

longitud de índice real utilizada

árbitro

Cuando se utiliza la consulta de equivalencia de la columna de índice, la información del objeto que coincide con la columna de índice para la equivalencia.

filas

Número estimado de registros a leer

filtrado

Para los registros estimados que deben leerse, el porcentaje de registros restantes después de filtrar por condiciones de búsqueda. No tiene sentido en una consulta de una sola tabla. En una consulta de tabla unida, puede calcular cuántas veces debe ejecutarse la consulta en la tabla controlada después de que la tabla del controlador complete la consulta.

Extra

Notas adicionales

La mayoría de estas columnas se han explicado con suficiente claridad en la información de descripción. A continuación detallamos principalmente algunas columnas necesarias:

1.1 seleccionar_tipo
  • SIMPLE: Consulta que no contiene UNION o subconsulta en la declaración de consulta

  • PRIMARIO: para una consulta grande que contiene UNION, UNION ALL o subconsulta, se compone de varias consultas pequeñas, en las que el tipo de selección de la consulta más a la izquierda es PRIMARIO

  • UNION: Para una consulta grande que contiene UNION y UNION ALL, se compone de varias consultas pequeñas. Excepto por la consulta pequeña más a la izquierda, el tipo de selección de las otras consultas pequeñas es UNION.

  • RESULTADO DE UNION: MySQL elige usar una tabla temporal para completar la deduplicación de consultas UNION. El tipo de selección de la consulta para esta tabla temporal es RESULTADO DE UNION.

  • UNIÓN DEPENDIENTE: tipos relacionados con consultas UNION

  • SUBCONSULTA, SUBCONSULTA DEPENDIENTE, MATERIALIZADA: tipos relacionados con subconsultas

  • DERIVADA: En una consulta que contiene una tabla derivada, la consulta se ejecuta como una tabla derivada materializada.

1.2 tipo
  • const: Ubique un registro mediante la comparación de igualdad de la clave primaria o el índice secundario único con una constante.Si es un índice conjunto, este acceso constante solo es válido cuando cada columna de la columna del índice se compara con la constante para la igualdad.

  • ref: Mediante una comparación equivalente entre el índice secundario y la constante, el intervalo de exploración formado es el acceso del intervalo de exploración de un solo punto.

  • ref_or_null: en comparación con ref, se escanean algunas columnas de índice secundarias con valores NULL.

  • rango: cuando se utiliza un índice para ejecutar una consulta, el intervalo de escaneo correspondiente es el acceso a varios intervalos de escaneo de un solo punto o intervalos de escaneo de rango.

  • índice: utilice un índice de cobertura y escanee el acceso a todos los índices secundarios. Además, al ejecutar una consulta en una tabla usando el motor InnoDB a través de un escaneo completo de la tabla, si se agrega una declaración de clave primaria ORDER BY , la declaración también se considerará un acceso de índice cuando se ejecute.

  • texto completo: acceso al índice de texto completo

  • todo: escaneo completo de la tabla

  • eq_ref: al ejecutar una consulta de combinación , si se accede a la tabla controlada a través de una clave principal o un índice secundario único que no permite NULL, coincidencia de valores iguales

En las uniones externas, la declaración ON se propone específicamente para el escenario en el que "cuando un registro en la tabla del controlador no puede encontrar un registro coincidente en la tabla controlada, cada campo del registro de la tabla controlada correspondiente se completa con NULL"; en las uniones internas, ON y WHERE tienen el mismo efecto

  • subconsulta_única: para algunas declaraciones de consulta que contienen subconsultas IN, si el optimizador de consultas decide convertir la subconsulta IN en una subconsulta EXISTS, y la subconsulta se puede ejecutar utilizando la clave principal o un índice secundario único que permita NULL después de la conversión .

  • index_subquery: similar a Unique_subquery, excepto que se utiliza un índice secundario normal al acceder

  • index_merge: La combinación de índice existe

  • sistema: cuando solo hay un registro en la tabla y las estadísticas del motor de almacenamiento utilizado son precisas (como MyISAM y MEMORIA)

1.3 árbitro

Cuando el método de acceso es uno de const, ref, ref_or_null, eq_ref, Unique_subquery e index_subquery, la columna ref muestra lo que es equivalente a la columna índice :

  • const: representa una constante

  • func: representa una función

  • DBName.TableName.columnName: representa una columna en una tabla de una base de datos

1.4 Adicional
  • No se utiliza ninguna tabla: no hay ninguna cláusula FROM en la declaración de consulta

  • Imposible DÓNDE: La condición DÓNDE en la declaración de consulta siempre es FALSA

  • No hay fila mínima/máxima coincidente: cuando hay una función agregada mínima o máxima en la consulta, pero ningún registro cumple con la condición WHERE

  • Usando Index: usando un índice de cobertura

  • Uso de la condición de índice: la función de inserción de condición de índice se utiliza al ejecutar la declaración de consulta.

Pushdown de condición de índice: está optimizado para las condiciones de consulta del índice secundario. Al juzgar las condiciones del índice secundario, se juzgarán todas las condiciones de las columnas relacionadas con el índice y luego se realizará la operación de retorno de la tabla si se cumplen las condiciones. Si Si se cumplen las condiciones, ya no se realizará el retorno de la tabla, lo que reduce el número de operaciones de retorno de la tabla y, por lo tanto, reduce la E/S. 

Ejemplos a continuación:

seleccione * de tabla_específica donde clave1 > 'a' y clave1 como '%b'; 

Al presionar hacia abajo la condición del índice se juzgarán todas las condiciones de la clave1 en lugar de regresar a la tabla solo después de juzgar la clave1 > 'a'.

  • Uso del búfer de unión (bucle anidado de bloque): indica que al ejecutar una consulta de unión, la tabla controlada no puede usar efectivamente el índice para acelerar el acceso, pero usa bloques de memoria para acelerar la consulta.

  • Usando intersect(index_name, ...), usando union(index_name, ...) y usando sort union(index_name, ...): indica el uso de combinación de índice de intersección, combinación de índice de unión o combinación de índice Ordenar-Unión para ejecutar la consulta. (abajo hay una introducción)

  • Uso de clasificación de archivos: clasificación de archivos, la clasificación no puede utilizar el índice y solo se puede ordenar en la memoria o el disco.

  • Uso temporal: la tabla temporal interna se utiliza durante la consulta

2. Consideraciones de optimización

Optimizar según el tipo de acceso

En el artículo anterior, hemos introducido en detalle el tipo de acceso (tipo) en la declaración EXPLAIN. Si el tipo de acceso de una consulta no es el que esperábamos, la solución más simple y directa es agregar un índice apropiado a la condición de búsqueda. columna .

Optimización para reducir el número de líneas de escaneo.

En algunos casos, simplemente agregar índices no resuelve el problema, como ejecutar el siguiente SQL:

 
  
select name, count(name) from specific_table group by key1;

Después de ejecutar este SQL, es posible que solo se devuelvan unas pocas filas de datos, pero debido a la función agregada COUNT, los datos que deben escanearse pueden ser miles de filas, dependiendo de la cantidad total de datos en la tabla. Para este tipo de situación en la que se escanea una gran cantidad de datos pero solo se devuelven unas pocas filas , generalmente se puede optimizar agregando una tabla de resumen separada . Por supuesto, esto requiere agregar la lógica correspondiente en la capa de aplicación para mantener los datos en el cuadro resumen.

Además, también puede optimizar reescribiendo consultas complejas . A continuación presentamos las instrucciones que deben tenerse en cuenta al reescribir consultas:

¿Una consulta compleja o varias consultas simples?

Ésta es una cuestión que vale la pena considerar. Divida las consultas complejas en varias consultas simples para reducir el trabajo de la base de datos tanto como sea posible y mueva parte de la lógica de procesamiento a la capa de aplicación para su procesamiento. Debido a que MySQL procesa consultas simples de manera muy eficiente, hacerlo generalmente puede mejorar la eficiencia.

Segmentación

En el trabajo real, al transferir (o eliminar) una tabla de base de datos con una gran cantidad de datos, el método de segmentación generalmente se usa para dividir una consulta grande en consultas pequeñas. La función de cada consulta es la misma, pero la operación La cantidad El número de datos es diferente. Después de ejecutar cada consulta pequeña, se completa la tarea de la consulta grande.

Transferir una gran cantidad de datos a la vez puede bloquear una gran cantidad de datos, ocupar todo el registro de transacciones, agotar los recursos del sistema y bloquear muchas consultas pequeñas. Para evitar esta situación, generalmente solo se operan 10,000 elementos en un reenvío de datos. tarea. Esto tendrá el menor impacto en el servidor, y cada vez que se completa la transferencia, se puede pausar por un tiempo antes de ejecutar la siguiente tarea. Esto puede distribuir la presión durante un período de tiempo más largo y reducir en gran medida el impacto en el servidor y reducir el tiempo que se mantiene el bloqueo.

Optimizar consultas de unión

Si hay demasiadas tablas conjuntas, debemos dividirlas en varias consultas o en varias consultas de una sola tabla ( la eficiencia de la caché de las consultas de una sola tabla será mayor ). Después de descomponer la consulta, la competencia de bloqueo entre consultas se reducirá . Además, al consultar tablas conjuntas, debe prestar atención a los dos puntos siguientes:

  • Asegúrese de que haya índices en las columnas de la cláusula ON o USING

  • Asegúrese de que cualquier expresión en GROUP BY y ORDER BY solo haga referencia a columnas en una tabla para que MySQL pueda usar el índice para optimizar la consulta.

Condición IN() y condición OR

En términos generales, pensamos que IN () es completamente equivalente a múltiples condiciones OR, pero existe una diferencia entre las dos en MySQL. Cuando MySQL maneja la condición IN (), primero ordenará los datos en la lista y luego usará la búsqueda binaria para determinar si los valores en la lista cumplen con la condición. Esta es una operación con una complejidad temporal de O (logn ) Si se convierte de manera equivalente en una consulta OR, su complejidad temporal es O (n), por lo que cuando hay una gran cantidad de valores en la condición IN (), MySQL procesará más rápido.

Si el índice no es válido durante la consulta
  • El índice no se puede utilizar si la búsqueda no comienza en la columna más a la izquierda del índice.

  • Si se omiten columnas en un índice de unión, el índice no se puede usar o solo se puede usar un índice parcial. Existe el siguiente SQL, donde key_part1, key_part2 y key_part3 son índices conjuntos en orden

 
  
select key_part1, key_part2, key_part3 from specific_table
where key_part1 = 1 and key_part3 = 3;

Si se omite key_part2 en la condición de consulta, solo se puede utilizar la primera columna del índice. Si se omite key_part1, no se puede utilizar el índice conjunto.

  • Si hay una consulta de rango para una columna en la consulta, todas las columnas a la derecha no pueden usar la optimización de índice para consultar u ordenar. En este caso, si el número de valores de la columna de consulta de rango es limitado, la consulta de rango se puede reemplazar por múltiples coincidencias iguales usando la conexión OR

  • Si el nombre de la columna en la condición de búsqueda no aparece solo en forma de nombre de columna, sino que usa una expresión o función, entonces no se puede usar el índice. Como se muestra en el siguiente SQL, la columna clave1 aparece en forma de clave1 * 2 y no se utilizará el índice.

 
  
select * from specific_table where key1 * 2 > 4;
  • Si utiliza una consulta difusa que comienza con % para un campo de longitud variable, no se utilizará el índice. Esto es más fácil de entender, porque MySQL ordena las cadenas carácter por carácter. Si usa% al principio, la comparación no se puede completar y solo puede usar un escaneo completo de la tabla.

Si el índice no es válido durante la clasificación
  • Si el orden de las columnas que siguen a la instrucción ORDER BY no se proporciona en el orden de las columnas del índice conjunto, el índice no se puede utilizar

  • Si ASC y DESC se mezclan, el índice no se puede utilizar

Existe el siguiente SQL, en el que key_part1 y key_part2 son índices conjuntos en orden y el índice no se puede utilizar durante la ejecución.

 
  
select key_part1, key_part2 from specific_table 
order by key_part1, key_part2 desc;

En MySQL versión 8.0, es posible admitir el uso mixto de índices ASC y DESC.

  • Si la columna de clasificación contiene columnas que no tienen el mismo índice, el índice no se puede utilizar, como se muestra en el siguiente SQL

 
  
select id, key1, key2 from specific_table order by key1, key2;

Debido a que no son el mismo índice, cuando la clave1 es la misma, no se ordenarán según la columna clave2, por lo que no se utiliza el índice.

  • Si las columnas de clasificación son columnas de índice de un índice conjunto, pero estas columnas de clasificación no son consecutivas en el índice conjunto, entonces el índice no se puede utilizar. Como se muestra en el siguiente SQL, debido a que el índice conjunto no está ordenado por key_part3 después de ordenar por key_part1, el índice no se puede utilizar.

 
  
select key_part1, key_part3 
from specific_table 
order by key_part1, key_part3;
  • Si la columna de clasificación no aparece como un nombre de columna independiente en la instrucción ORDER BY, no se puede utilizar el índice. Como se muestra en el siguiente SQL, se usa una función durante la clasificación, por lo que no se puede usar el índice

 
  
select id, key1, key2 from specific_table order by upper(key1)
Optimización de que las columnas de índice no estén vacías

Cuando se requieren operaciones Min() y Max(), tener columnas de índice que no sean nulas puede hacerlas más eficientes. Por ejemplo, para encontrar el valor mínimo de una determinada columna, solo necesita consultar el registro más a la izquierda del índice correspondiente del árbol B. El optimizador de consultas tratará esta expresión como una constante y podrá encontrar "Seleccionar tablas optimizadas" en la columna Extra del resultado de ESPLAIN.

Índices duplicados y redundantes

Los índices duplicados se refieren al mismo tipo de índices creados en las mismas columnas en el mismo orden, como se muestra en el siguiente SQL:

 
  
create table specific_table (
    id int not null primary key,
    unique key(id)
)engine=InnoDB;

Crea dos índices idénticos en la columna de identificación y es necesario eliminar el índice único.

Los índices redundantes generalmente ocurren cuando se agrega un nuevo índice a una tabla, como agregar un índice (columna_a, columna_b) a un índice existente (columna_a). Esta es la situación en la que ocurre un índice redundante, porque el segundo índice conjunto puede reproducirse de la misma manera. función como índice de una sola columna.

En la mayoría de los casos, no se necesitan índices redundantes y deberíamos intentar ampliar los índices existentes en lugar de crear otros nuevos.

¿Existe una fusión de índices?

La creación de varios índices de una sola columna de forma independiente en varias columnas no mejora el rendimiento de las consultas MySQL en la mayoría de los casos.

Existe una estrategia de "fusión de índices" en MySQL, que puede utilizar múltiples índices de una sola columna en la tabla para ubicar filas de datos específicas y fusionar los resultados del escaneo. La estrategia de fusión de índices a veces es muy buena, pero más a menudo muestra que los índices de la tabla están mal construidos :

  • Cuando el optimizador de consultas necesita fusionar varios índices, generalmente significa un índice de unión que contiene todas las columnas relevantes, en lugar de múltiples índices independientes de una sola columna.

  • Cuando el optimizador necesita fusionar varios índices, generalmente necesita consumir una gran cantidad de recursos de CPU y memoria en las operaciones de almacenamiento en caché, clasificación y fusión del algoritmo, especialmente cuando algunos de los valores de las columnas del índice no son altamente selectivos y necesidad de fusionar resultados de escaneo de grandes cantidades de datos

  • El optimizador no contará estas operaciones en el costo de la consulta, lo que hará que el costo de la consulta se "subestime", lo que hará que el plan de ejecución sea peor que un escaneo completo de la tabla.

En términos generales, debemos considerar reconstruir el índice o usar UNION para reescribir la consulta. Además, la función de combinación de índices se puede desactivar modificando el parámetro optimizador_switch, como se muestra en el siguiente SQL:

 
  
SELECT @@optimizer_switch;


-- 改成 index_merge=off 
set optimizer_switch = 'index_merge=off, ...';

También puede utilizar la sintaxis IGNORE INDEX para permitir que el optimizador ignore ciertos índices, evitando así que el optimizador combine planes de ejecución utilizando índices que incluyan el índice:

 
  
select * from specific_table ignore index(index_name)
where column_name = #{value};

Además de considerar ignorar el índice cuando se produce una combinación de índice, también debe considerar ignorar el índice y utilizar un escaneo completo de la tabla cuando no se puede formar un intervalo de escaneo adecuado al ejecutar una consulta y el propósito de reducir la cantidad de registros de escaneo no puede ser logrado.

A continuación presentamos tres tipos de combinación de índices, para que todos puedan tener una comprensión más completa de la combinación de índices: son la combinación de índices de intersección, la combinación de índices de unión y la combinación de índices de clasificación y unión .

Fusión de índice de intersección

Veamos la siguiente consulta:

select * from specific_table where key1 = 'a' and key2 = 'b';

Lo que todos sabemos es que cuando los valores de la columna de índice son los mismos, los registros del índice secundario se ordenan según el tamaño del valor de la clave principal , luego el valor de la clave principal se filtra por clave1 y el valor de la clave principal se filtra por key2 se puede intersectar . y luego ejecutar la operación de retorno de tabla según los resultados. Esto es menos costoso que devolver los valores de clave principal filtrados para key1 y key2 respectivamente. En este caso, se utiliza la estrategia de fusión de índice de intersección.

Union 索引合并

Veamos la siguiente consulta:

 
  
select * from specific_table where key1 = 'a' or key2 = 'b';
Tome la unión de los valores de clave principal filtrados por clave1 y los valores de clave principal filtrados por clave2 , y luego realice la operación de retorno de la tabla según los resultados. Este método se denomina fusión de índice de unión, que puede compararse a hacer directamente un escaneo completo de la tabla. La sobrecarga debe ser baja. Cabe señalar que la fusión del índice Union requiere que los valores de clave primaria filtrados por el índice secundario estén en orden. Si los valores de clave primaria están desordenados, se debe considerar la fusión del índice Sort-Union.
Fusión de índice Sort-Union

Existe la siguiente consulta:

 
  
select * from specific_table where key1 < 'a' or key2 > 'b';

Cambiamos las condiciones de consulta anteriores a condiciones de consulta de rango. Ahora los valores de clave principal filtrados por cada índice están desordenados, por lo que no se puede utilizar la combinación de índices de unión. La combinación de índices de clasificación y unión se agrega sobre la base de la combinación de índices de unión. Operación de clasificación: ordene , de modo que pueda continuar usando el índice de unión para fusionar.

Optimizar CONTAR()

Cuando necesitamos contar resultados con valores , necesitamos especificar el nombre de la columna o COUNT(0) en la condición COUNT(); cuando necesitamos contar todas las filas , necesitamos especificar COUNT(*), que ignorará todas las columnas. y Cuente todas las filas directamente. Después de comprender estos dos puntos, podemos comunicar nuestras intenciones con mayor claridad al realizar estadísticas de datos.

En términos generales, las consultas COUNT() necesitan escanear una gran cantidad de filas de datos para obtener resultados precisos, por lo que son difíciles de optimizar. Si el escenario empresarial no requiere una precisión total, podemos usar EXPLAIN para estimar el número de filas , o podemos eliminar algunas restricciones en las condiciones de la consulta y eliminar DISTINCT para evitar operaciones de clasificación. Estas prácticas pueden mejorar el rendimiento de las consultas estadísticas.

Optimización de consultas UNION

Cuando usamos la consulta UNION, si no necesitamos eliminar filas duplicadas, debemos usar UNION ALL, porque si no hay una palabra clave ALL, MySQL agregará DISTINCT a la tabla temporal, lo que deduplicará los datos y el costo es relativamente alto. . Además, podemos aplicar declaraciones WHERE, LIMIT y ORDER BY a cada consulta, lo que permite a MySQL optimizarlas mejor.

Optimizar DESPLAZAMIENTO

En las consultas de paginación, OFFSET hará que MySQL escanee una gran cantidad de filas innecesarias y luego las descarte. Por ejemplo, la expresión LIMIT 1000, 20 consultará 1020 datos y luego descartará los primeros 1000. Esto es muy costoso.

Podemos usar marcadores para registrar la "posición" donde se leyeron los datos por última vez, de modo que la siguiente consulta pueda comenzar a escanear directamente desde esa posición, evitando el uso de OFFSET. Por ejemplo, cada página muestra 20 datos y registramos que el valor de ID de datos de la página actual es 200. Luego, cuando miramos los datos de la página siguiente, la consulta SQL es la siguiente:

 
  
select * from specific_table
where id <= 180
limit 20;

Sin embargo, esta situación también tiene desventajas: no puede especificar el número de página para la consulta. Por ejemplo, si quiero ver los datos en la página 5, no podemos calcular el rango de valores de ID específicos de la página correspondiente. A menos que podamos asegurarnos de que el valor de ID aumente monótonamente y no se hayan eliminado datos, en este caso, el valor de ID es continuo, podemos calcular fácilmente que el valor de ID de los datos en la página 5 comienza desde 120. La ventaja de esto es que funciona muy bien sin importar qué tan atrás se pase la página.

Utilice CON ROLLUP para optimizar GROUP BY

Generalmente usamos GROUP BY para realizar consultas de agregación de grupos, si queremos sumar los resultados agrupados nuevamente, podemos usar la operación CON ROLLUP, pero una mejor manera es llevar el procesamiento CON ROLLUP a la capa de aplicación.

OPTIMIZAR TABLA

Si eliminamos muchos datos , o al insertar datos, no se insertan en el orden creciente de la clave principal , es probable que se produzcan muchos fragmentos de memoria, lo que afectará la eficiencia de la consulta de datos. Esto se debe a que cuando se eliminan datos, MySQL no los borra ni organiza el espacio inmediatamente, sino que los marca para su eliminación. OPTIMIZE TABLE se puede utilizar para organizar el espacio y reducir la fragmentación de la memoria.

El motor InnoDB no admite la operación OPTIMIZAR TABLA y mostrará el siguiente mensaje:

 
  
OPTIMIZE TABLE specific_table;


-- Table does not support optimize, doing recreate + analyze instead

Podemos reconstruir la expresión para el propósito anterior mediante el comando ALTER sin realizar ninguna operación:

 
  
alter table specific_table engine=InnoDB;

Una vez completada la ejecución, verificamos el estado de ejecución a través del siguiente SQL: si la columna data_free es 0, significa que nuestra desfragmentación del espacio fue exitosa.

 
  
show table status from specific_db like specific_table;

Sin embargo, en la mayoría de los casos esto no es necesario.

Buscar y reparar tablas corruptas

El índice puede estar dañado debido a problemas de hardware, defectos del propio MySQL o problemas del sistema operativo. Por supuesto, este problema es muy raro. Podemos verificar la mayoría de los errores de tablas e índices a través del siguiente SQL:

 
  
check table specific_table;

Si se encuentra una excepción, se puede reparar mediante el siguiente SQL:

 
  
repair table specific_table;


-- 如果存储引擎不支持上述操作的话,也可通过表重建来完成
alter table specific_table engine=InnoDB;

Referencias:

[1] "Cuarta edición de MySQL de alto rendimiento": Capítulos 7 y 8

[2] "Cómo funciona MySQL": Capítulos 7, 10, 11, 14 y 15

[3] MySQL: optimizador_interruptor

[4] 8.9.4 Sugerencias de índice

[5] Mysql avanzado: comando optimizar tabla

-fin-

Supongo que te gusta

Origin blog.csdn.net/jdcdev_/article/details/133565446
Recomendado
Clasificación