Un resumen de la optimización de mySQL Requisitos generales para la escritura de SQL

 

Requisitos generales para la escritura de SQL
--- Las sentencias de SQL son lo más simples posible
--- descomponer y unir para garantizar una alta concurrencia
--- comparar valores de columna del mismo tipo de datos
--- no realizar operaciones en columnas indexadas
- - no no utilizar SELECT *
--- negativo evitar para consulta y% prefijo consulta difusa
--- mantener la transacción (conexión) corto
--- reescritura O a IN ()
--- reescritura O a UNION
--- LIMIT paginación eficiente
--- use UNION ALL en lugar de UNION
--- GROUP BY eliminar ordenación

La declaración SQL es lo más simple posible

l Big SQL VS múltiple SQL simple

Ø Ideas de diseño tradicionales

Ø PERO MySQL NO

Ø Un SQL solo se puede operar en una CPU

Ø En la alta concurrencia de más de 5000 QPS, ¿qué significa 1 segundo de SQL grande?

Ø Un gran SQL puede bloquear toda la base de datos

l Rechazar SQL grande y desarmarlo en múltiples SQL simples

Ø La tasa de aciertos de la caché de SQL simple es mayor

Ø Reducir el tiempo de la mesa de bloqueo

Ø Utilice varias CPU

 

Descomponer la conexión para garantizar una alta concurrencia

l No se recomienda una base de datos altamente concurrente para JOIN de más de dos tablas

l Descomponer correctamente las conexiones para garantizar una alta concurrencia

Ø Se puede almacenar en caché una gran cantidad de datos iniciales

Ø Utilice la función IN para el ID de una mesa grande

Ø La conexión hará referencia a la misma tabla varias veces

l Ejemplos

MySQL> Seleccione post_name de la etiqueta JOIN tag_post

               en tag_post.tag_id = tag.id JOIN post

               en tag_post.post_id = post.id

               WHERE tag.tag = 'Juguetes de segunda mano';

MySQL> Seleccione tag_id de la etiqueta WHERE tag = 'Juguetes de segunda mano';

MySQL> Seleccione post_id de tag_post DONDE tag_id = 1321;

MySQL> Seleccione post_name de la publicación DONDE post.id in (123,456,314,141);

 

Comparación de valores de columna del mismo tipo de datos

l Principio: número a número, carácter a carácter

l Comparación de columnas numéricas y tipos de caracteres

Ø Convertir a doble precisión al mismo tiempo

Ø Comparar

l Columna de caracteres y comparación de tipo numérico

Ø La columna de caracteres se convierte en un valor numérico

Ø No utilizará la consulta de índice

 

No realizar operaciones en columnas de índice

l No realice operaciones matemáticas ni operaciones digitales en la columna de índice

Ø No se puede utilizar el índice

Ø Causa un escaneo completo de la tabla

l Ejemplos

 

Prohibir el uso de SELECT *

l Al usar SELECT *

Ø Más consumo de CPU, memoria, IO, ancho de banda de red

Ø Primero solicite todas las columnas de la base de datos y luego descarte las columnas innecesarias.

l Trate de no SELECCIONAR *, solo busque las columnas de datos requeridas

ØDiseño más seguro: reduce el impacto de los cambios de mesa

ØProporcionar la posibilidad de utilizar índice de cobertura

ØSelect / JOIN reduce la generación de tablas temporales del disco duro, especialmente cuando hay TEXT / BLOB

l Ejemplos

SELECCIONAR * DESDE la etiqueta DONDE id = 999184;

SELECCIONE la palabra clave DESDE la etiqueta DONDE id = 999184;

Evite la consulta negativa y la consulta difusa de% prefijo

l Evite consultas negativas

ØNO 、! = 、 <> 、! <、!> 、 NO EXISTE 、 NO EN 、 NO ME GUSTA 等

l Evite la consulta difusa de% prefijo

ØB + Árbol

ØNo se puede utilizar el índice

Ø Conducir a un escaneo completo de la tabla

l Ejemplos

 MySQL> seleccione * de la publicación DONDE título como '北京%';

 298 filas en conjunto (0.01 seg)

 MySQL> seleccione * de la publicación DONDE título como '% 北京%';

 572 filas en conjunto (3,27 seg)

 

Mantenga las transacciones (conexiones) breves

Mantenga las transacciones / conexiones de base de datos breves y concisas

Ø Principio de uso de transacción / conexión: abrir y usar, cerrar cuando se agote

Ø Las operaciones irrelevantes para la transacción se colocan fuera de la transacción para reducir la ocupación de los recursos de la cerradura.

Ø Bajo la premisa de no destruir la coherencia, use múltiples transacciones cortas en lugar de transacciones largas

 

Reescribir OR en IN ()

l En el mismo campo, reescribe o como en ()

Ø O eficiencia: O (n)

Ø Eficiencia IN: O (Log n)

Ø Cuando n es grande, OR será mucho más lento

l Preste atención para controlar el número de IN, se recomienda que n sea menor que 300

l Ejemplos

Seleccione * de opp WHERE phone = '12347856' o phone = '42242233';

Seleccione * de opp WHERE teléfono en ('12347856', '42242233');

Reescribir OR en UNION

l Diferentes campos, cambio o unión

Ø Reducir las consultas "o" para diferentes campos

Ø ¡El índice de fusión es a menudo muy retrasado mental!

l Ejemplos

Seleccione * de opp WHERE phone = '010-88886666' o cellPhone = '13800138000';

 

Seleccione * de opp WHERE phone = '010-88886666'

Unión

Seleccione * de opp DONDE cellPhone = '13800138000';

 

LÍMITE de paginación eficiente (1)

l Paginación tradicional:

Ø Seleccionar * del límite de la tabla 10000,10;

Principio lLIMIT:

Ø Límite 10000,10

Ø Cuanto mayor sea el desplazamiento, más lento

l Paginación recomendada:

Seleccione * de la tabla DONDE id> = 23423 límite 11; # 10 + 1 (10 entradas por página)

seleccione * de la tabla DONDE id> = 23434 límite 11;

 

LÍMITE de paginación eficiente (dos)

l Modo de paginación dos:

Seleccione * de la tabla DONDE id> = (seleccione la identificación del límite de la tabla 10000,1) límite 10;

l Modo de paginación tres:

SELECT * FROM table INNER JOIN (SELECT id FROM table LIMIT 10000,10) USING (id);

l Modo de paginación cuatro:

Ø Identificación de búsqueda del programa: seleccione la identificación del límite de la tabla 10000,10;

Ø Seleccione * de la tabla DONDE id en (123,456…);

l Es posible que deba analizar y reorganizar el índice de acuerdo con la escena

 

LÍMITE de paginación eficiente (3)

l Ejemplo

MySQL> seleccione sql_no_cache * del límite de publicación 10,10;

10 filas en conjunto (0.01 seg)

MySQL> seleccione sql_no_cache * del límite de publicación 20000,10;

10 filas en conjunto (0,13 seg)

MySQL> seleccione sql_no_cache * del límite de publicación 80000,10;

10 filas en conjunto (0,58 seg)

MySQL> seleccione sql_no_cache id del límite de publicación 80000,10;

10 filas en conjunto (0.02 seg)

MySQL> seleccione sql_no_cache * de la publicación WHERE id> = 323423 límite 10;

10 filas en conjunto (0.01 seg)

MySQL> seleccione * de la publicación WHERE id> =

(seleccione sql_no_cache id del límite de publicación 80000,1) límite 10;

10 filas en conjunto (0.02 seg)

 

Utilice UNION ALL en lugar de UNION

l Si no necesita desduplicar los resultados, use UNION ALL

ØUNION tiene una sobrecarga de deduplicación

l Ejemplos

MySQL> SELECT * FROM detail20091128 UNION ALL

               SELECCIONAR * DESDE el detalle 20110427 UNIÓN TODO

               SELECCIONAR * DESDE el detalle 20110426 UNIÓN TODO

               SELECCIONAR * DEL detalle 20110425 UNIÓN TODO

               SELECCIONAR * DEL detalle 20110424 UNIÓN TODO

               SELECCIONAR * DE detail20110423;

 

GROUP BY eliminar ordenar

lGROUP POR implementación

Ø Grupo

Ø clasificación automática

l No se requiere clasificación: ordenar por NULL

l Orden específica: Agrupar por DESC / ASC

l Ejemplos

MySQL> seleccione teléfono, cuente (*) del grupo de publicaciones por límite de teléfono 1;

1 fila en conjunto (2,19 seg)

MySQL> seleccione el teléfono, cuente (*) del grupo de publicaciones por orden de teléfono por límite nulo 1;

1 fila en conjunto (2,02 seg)

 

-------------------------------------------------- --------------

http://www.taobaodba.com/html/851_sql%E4%BC%98%E5%8C%96%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%BB% E7% BB% 93.html La optimización de SQL es una parte indispensable del trabajo diario de DBA. Recuerdo que cuando era estudiante, vi una publicación en ITPUB. En ese momento, el anfitrión usó una fórmula para explicarlo cuando introdujo SQL Optimización. Principios a seguir al realizar la optimización de SQL:

          T = S / V (T significa tiempo, S significa distancia, V significa velocidad)

S se refiere a la cantidad total de recursos a los que SQL necesita acceder, V se refiere a la cantidad de recursos a los que puede acceder SQL por unidad de tiempo, T es naturalmente el tiempo requerido para la ejecución de SQL; para obtener el tiempo de ejecución más rápido de SQL, podemos revertirlo de acuerdo con la definición de la fórmula:

  1. En el caso de S sin cambios, podemos aumentar V para reducir T: a través del ajuste de índice apropiado, podemos convertir una gran cantidad de IO aleatorias más lentas en IO secuenciales más rápidas; al aumentar la memoria del servidor, poner más datos en la memoria obtendrá un aumento significativo de la velocidad que poner los datos en el disco; los SSD que usan medios de almacenamiento electrónicos para el almacenamiento y lectura de datos rompen el cuello de botella de rendimiento de los discos duros mecánicos tradicionales, haciéndolos extremadamente altos El rendimiento de almacenamiento de la V; podemos usar hardware de configuración superior para completar la mejora de la velocidad en la promoción de V;
  2. Cuando V no cambia, podemos reducir S para reducir T: esta es una parte muy central de la optimización de SQL. Al reducir S, hay muchas cosas que DBA puede hacer, que generalmente se pueden establecer en condiciones de consulta Índices apropiados para evitar una tabla completa escaneo; a veces puede reescribir SQl y agregar algunas indicaciones apropiadas para cambiar el plan de ejecución de SQL para que SQL pueda completar la consulta con la menor ruta de escaneo; cuando estos métodos se agotan, ¿hay otras opciones para optimizar Nan? Hay un artículo en la descripción del trabajo del DBA del departamento de Ali que requiere que el DBA tenga un conocimiento profundo del negocio. Una vez que el DBA tiene un conocimiento profundo del negocio, este tiempo puede considerarse desde la perspectiva del negocio. y el DB. En este momento, está optimizado. El tiempo puede lograr el efecto de obtener el doble de resultado con la mitad del esfuerzo.

Caso 1: Aumente T bajando S

Introducción al principio:
sabemos que el valor del nodo hoja del índice B + está en orden ascendente de acuerdo con el campo del índice. Por ejemplo, si indexamos los dos campos (nick, appkey), entonces el índice en el índice se organiza en orden ascendente de nick y appkey; si el sql actual:
seleccione count (nick distinto) de xxxx_nickapp_09_29; se
usa para consultar y contar el UV en la tabla de registro en un día determinado. El optimizador selecciona el índice ind_nick_appkey (nick, appkey) en el tabla para completar la consulta, y luego comienza uno desde nick1 Escaneando la barra hacia abajo hasta que se escanea el último nick_n, luego el proceso intermedio escaneará muchos nicks repetidos (el escaneo normal más a la izquierda). Si podemos omitir los nicks intermedios repetidos, el rendimiento se optimizará mucho (el escaneo suelto más a la derecha):

Se puede sacar una conclusión de lo anterior:

Si el sql de esta estadística uv se puede escanear en la forma de escaneo de índice suelto a la derecha, reducirá en gran medida la S que mencionamos anteriormente; por lo que necesitamos reescribir el sql para lograr el escaneo de índice pseudo suelto: (el optimizador MySql no puede Optimizar directamente el recuento (columna distinta))

root @ DB 09:41:30> seleccione recuento (*) de (seleccione distinto (nick) de xxxx_nickapp_09_29) t;
+ ———- +
| recuento (*) |
+ ———- +
| 806934 |
+ —— —- + En la
consulta interna de Sql, primero seleccione diferentes nicks y, finalmente, establezca una capa de recuento en el exterior, puede obtener la suma de los distintos valores de nicks; lo
más importante está en la subconsulta: seleccione distinto (nick ) se da cuenta de la figura anterior El escaneo de índice pseudo suelto, el plan de ejecución del optimizador en este momento es Usar índice para agrupar, por lo que mysql optimiza el distinto para agrupar, primero use el índice para agrupar, luego escanee el índice, escanee solo uno grabar para el nick requerido.

escenario de caso real:

Este caso se selecciona de un sistema de producción en línea nuestro. El sistema tiene una gran cantidad de datos de registro almacenados en la base de datos todos los días. La capacidad de una sola tabla es entre 10G-50G, y luego se realiza un análisis de resumen. uv en los datos de registro es uno de los lógicos, Sql es el siguiente:

seleccione el recuento (nick distinto) de xxxx_nickapp_09_29;

Incluso si el índice de nick se agrega a la subtabla _xxxx, al ver el plan de ejecución, es un escaneo de índice completo. Debido a que la cantidad de datos en una sola tabla es demasiado grande, cuando se ejecuta SQL, traerá jitter a todo el servidor, y el SQL original se reescribió para admitir escaneo de índice suelto;

Antes de la optimización:

root @ DB 09:41:30> seleccionar recuento (nick distinto) de xxxx_nickapp_09_29;
+ ———- +
| contar (*) |
+ ———- +
| 806934 |

1 fila en conjunto (52,78 s) Se
necesitan 52,78 s para ejecutar SQL una vez

Optimizado:

root @ DB 09:41:30> seleccionar recuento (*) de (seleccionar distinto (nick) de xxxx_nickapp_09_29) t;

+ ———- +
| contar (*) |
+ ———- +
| 806934 |
+ ———- +
1 fila en conjunto (5,81 segundos)

De 52,78 segundos a 5,81 segundos, la velocidad aumentó casi 10 veces;

Ver el plan de ejecución de SQL:

Escritura optimizada:

root @ DB 09:41:30> explique el recuento de selección (*) de (seleccione distinto (nick) de xxxx_nickapp_09_29) t;

+ —- + ————- + ——————————— + ——- + ————— + ——————————— + ——— + —–
| id | select_type | mesa | tipo | posibles_keys | clave | key_len | ref | filas | Extra |
+ —- + ————- + ——————————— + ——- + ————— + ——————————— + ——— + —–
| 1 | SIMPLE | xxxx_nickapp_09_29 | rango | NULL | ind_nick_appkey | 67 | NULL | 2124695 | Utilizando índice para agrupar |
+ —- + ————- + —————————— + ——- + ————— + ——————————— + ——— + —–
原始写法 :
root @ DB 09:41:50> explicar el recuento de selección (nick distinto) de xxxx_nickapp_09_29;
+ —- + ————- + —————————— + ——- + ————— + —————————- + ——— + —— + -
| id | select_type | mesa | tipo | posibles_keys | clave | key_len | ref | filas | Extra |
+ —- + ————- + —————————— + ——- + ————— + —————————- + ——— + —— + -
| 1 | SIMPLE | xxxx_nickapp_09_29 | índice | NULL | ind_nick_appkey | 177 | NULL | 19546123 | Usando índice |
+ —- + ————- + ——————————— + ——- + ————– + —————————- + ——— + —— + -

Se puede ver que nuestra distancia se ha reducido de 19546123 a 2124695, que es más de 9 veces menor. ^ _ ^

Caso 2: Combinándolo con las características de escritura de los negocios en crecimiento, optimice ingeniosamente el recuento de estadísticas UV (*)

A veces pienso que el nivel más alto de optimización de un SQL es hacer posible eliminar este SQL del sistema. De todos modos, estos se basan en su suficiente conocimiento del negocio, y puede promover la actualización o descarga de algunos productos comerciales. Line, ¿puedes hacerlo con tal DBA?

Echemos un vistazo a un caso: la aplicación contará el número total de subtablas que hay en la base de datos todos los días: seleccione el recuento (*) de xx_01_01;
A medida que la cantidad de datos en una sola tabla aumenta cada vez más (single tabla es de alrededor de 20G), cuente cada vez En ese momento, la velocidad es cada vez más lenta, y es necesario escanear más bloques de páginas de datos al mismo tiempo, lo que conduce a la inestabilidad de todo el rendimiento de la base de datos. Al analizar las características del negocio, ya que cada tabla utiliza una identificación de aumento automático para la inserción y no se eliminan datos, por lo que se puede solucionar el número total de la tabla completa:

Entonces, este sql: select count (*) from xx_01_01;
se puede cambiar a: select max (id) -min (id) +1 from xx_01_01; la
velocidad de ejecución puede dar un salto cualitativo ^ _ ^.

Caso 3: Reducir T aumentando V: E / S aleatoria VS E / S secuencial

            Como mencionamos anteriormente, algunos métodos para mejorar V generalmente se pueden lograr mejorando el hardware del servidor, pero para muchas pequeñas y medianas empresas, el costo relativamente alto aún está fuera de su alcance y no existe una experiencia madura en el uso. Todavía puede ser algo malo para ellos. En general, independientemente del hardware de su servidor, si el SQL está mal escrito y el índice no está bien construido, todavía no funcionará.

Caso real en línea: una de nuestras bibliotecas de productos principales contiene una gran cantidad de lecturas aleatorias, así que llamémoslo bibliotecas de lectura. La carga de lectura de la biblioteca en un día es muy alta. A través del registro lento, se encuentra que hay un SQL que aparece con frecuencia en el día lento. Las condiciones de consulta de este SQL son muy complicadas. Al mismo tiempo, hay muchos índices similares en la tabla. Sospecha que el índice es incorrecto, use explicar para ver el plan de ejecución de SQL: se encuentra que el uso de where en el plan de ejecución representa la consulta de regreso a la tabla, y la gran cantidad de registros devueltos a la tabla trae muchos IO aleatorios:

Por lo tanto, solo necesitamos redundancia del campo is_detail en el índice original para optimizar el sql cubriendo el índice, evitando io aleatorio causado por volver a consultar la tabla, reemplazando el io aleatorio original con io secuencial, y la velocidad de ejecución de SQL ha sido muy mejorado: (la siguiente figura eliminará la prueba del campo is_detail) 

Resumen: La optimización de SQL es algo muy interesante. En nuestro trabajo diario, podemos optimizar de acuerdo con la idea de t = s / v. Tal vez no esté familiarizado cuando lo usa por primera vez, pero siempre y cuando sigues practicando, eres bueno resumiendo. También encontrarás las reglas, lo cual es realmente maravilloso. También es muy importante que su optimización de SQL no esté divorciada del negocio real. Tal vez dedicó una hora a optimizar un SQL, pero al discutir los resultados de la optimización con los estudiantes de desarrollo, los estudiantes de desarrollo dijeron que este SQL en realidad se puede descargar en línea, Realmente no pude reír ni llorar en ese momento

Supongo que te gusta

Origin blog.csdn.net/liuming690452074/article/details/113820229
Recomendado
Clasificación