Este artículo lo lleva a comprender el método de acceso a una sola tabla de MySQL

prefacio

Para nosotros MySQLlos usuarios, MySQLen realidad es una pieza de software, que es la que más usamos 查询功能. DBADe vez en cuando, echar un poco 慢查询语句de optimización, si ni siquiera sabemos cómo se ejecuta la consulta, qué deberíamos optimizar, así que es hora de dominar la tecnología real.

1. Preparación de datos

En el artículo anterior, sabemos que MySQL Serverhay un 查询优化器módulo llamado . Después de analizar una declaración de consulta, se entregará al optimizador de consultas para su optimización. El resultado de la optimización es generar un llamado plan de ejecución. Esta ejecución El plan muestra qué índices se deben usar para la consulta, cuál es la secuencia de conexión entre las tablas y, finalmente, se llamará al método proporcionado por el motor de almacenamiento de acuerdo con los pasos del plan de ejecución para ejecutar realmente la consulta y el resultado de la consulta. será devuelto al usuario. Sin embargo, el tema de la optimización de consultas es un poco amplio y debe aprender a usarlo antes de aprender a ejecutarlo, por lo que en este capítulo, primero veamos cómo MySQL ejecuta consultas de una sola tabla (es decir, , solo hay una tabla detrás de la instrucción from, el tipo de consulta más simple~). Sin embargo, una cosa para enfatizar es que debe leer las partes anteriores sobre la estructura de registros, la estructura de la página de datos y el índice antes de estudiar este capítulo. Si no puede garantizar que haya dominado completamente estas cosas, entonces este capítulo no es adecuado para usted.

Para que podamos estudiar sin problemas, primero creamos una tabla:

mysql> USE testdb;

mysql> create table demo8 (    
id int not null auto_increment,    
key1 varchar(100),    
key2 int,    
key3 varchar(100),    
key_part1 varchar(100),    
key_part2 varchar(100),    
key_part3 varchar(100),    
common_field varchar(100), 
primary key (id),
key idx_key1 (key1),    
unique key idx_key2 (key2),    
key idx_key3 (key3),    
key idx_key_part(key_part1, key_part2, key_part3));

Se ha creado un total de 1 índice agrupado (clave principal) y 4 índices secundarios para la tabla demo8:

  • Un índice agrupado creado para la columna id;
  • Un índice secundario creado para la columna key1;
  • Un índice secundario único creado para la columna key2;
  • Un índice secundario creado para la columna key3;
  • Índice secundario compuesto (conjunto) creado para las columnas key_part1, key_part2, key_part3.

Luego, debemos insertar 20,000 registros para esta tabla e insertar valores aleatorios en todas las columnas, excepto en la columna de identificación.

mysql> delimiter //
create procedure demo8data()
begin    
	declare i int;    
	set i=0;    
	while i<20000 do        
		insert into demo8(key1,key2,key3,key_part1,key_part2,key_part3,common_field) values(substring(md5(rand()),1,2),i+1,substring(md5(rand()),1,3),substring(md5(rand()),1,4),substring(md5(rand()),1,5),substring(md5(rand()),1,6),substring(md5(rand()),1,7));        
		set i=i+1;    
	end while;
end;
//
delimiter ;

mysql> call demo8data();

2. Método de acceso a una sola tabla

2.1 El concepto de método de acceso

Todos tuvimos la experiencia de consultar un diccionario cuando estábamos en la escuela primaria, cuando nuestro vocabulario no ha llegado a cierto nivel, si queremos saber la definición de una palabra que nunca hemos visto antes, necesitamos buscarla en un diccionario. En circunstancias normales, primero iremos al directorio del diccionario para encontrar el pinyin o los radicales chinos correspondientes, ubicaremos el número de página de la palabra y luego iremos directamente al número de página correspondiente para ver la definición correspondiente. También hay una situación en la que los diccionarios con cientos de páginas se pueden buscar página por página desde la primera página hasta la última página cuando está muy inactivo, y finalmente puede encontrarlo. Ambas formas pueden obtener los resultados que queremos, pero el tiempo y la energía gastados son muy diferentes. Lo mismo es cierto para MySQL Para acelerar la consulta de datos, se propone el concepto de índice de árbol B+. Pero a veces, si queremos consultar todos los datos, tenemos que recorrer todas las páginas de datos línea por línea y página por página para obtener los resultados.

Para la consulta de una sola tabla, los métodos de ejecución de la consulta MySQL se dividen aproximadamente en los siguientes dos tipos:

2.1.1 Consulta usando exploración de tabla completa

Este método es lo que dije anteriormente, atravesar registros línea por línea, página por página y agregar los registros que cumplen con las condiciones de búsqueda al conjunto de resultados. Aunque este método puede satisfacer nuestras necesidades, la eficiencia es sin duda la más baja.

2.1.2 Consulta con índices

Ejecutar la consulta directamente usando el método de exploración de tabla completa requiere atravesar muchos registros y el costo puede ser muy alto. Al igual que buscamos caracteres chinos a través del directorio del diccionario, si las condiciones de búsqueda en la declaración de consulta de MySQL pueden usar un índice, entonces usar directamente el índice para ejecutar la consulta puede acelerar el tiempo de ejecución de la consulta. Las formas en que se utilizan los índices para realizar consultas se pueden dividir en muchas categorías:

  • Consultas de equivalencia contra claves primarias o índices secundarios únicos
  • Consultas de equivalencia contra índices secundarios comunes
  • Consulta por rango de columnas indexadas
  • Al escanear directamente todo el índice

resumen

La forma en que MySQL ejecuta una declaración de consulta se denomina método de acceso o tipo de acceso. La misma declaración de consulta se puede ejecutar usando una variedad de métodos de acceso diferentes.Aunque los resultados finales de la consulta son los mismos, la eficiencia de la ejecución varía ampliamente.

inserte la descripción de la imagen aquí

2.2 constante

Localice un registro por su columna de clave principal:

mysql> select * from demo8 where id=9999;
+------+------+------+------+-----------+-----------+-----------+--------------+
| id   | key1 | key2 | key3 | key_part1 | key_part2 | key_part3 | common_field |
+------+------+------+------+-----------+-----------+-----------+--------------+
| 9999 | 34   | 9999 | 6c7  | 1823      | 24955     | 5deed4    | 3aebe82      |
+------+------+------+------+-----------+-----------+-----------+--------------+
1 row in set (0.00 sec)

¿Todavía recuerda la estructura del árbol B+ del índice agrupado en el índice del árbol B+ de MySQL? columna de identificación de clave de menor a mayor. El árbol B+ es originalmente un hombre bajo y gordo, con atributos únicos, ordenados y no vacíos, la velocidad de localizar un registro según el valor de la clave principal es muy rápida. De manera similar, es muy rápido ubicar un registro basado en la columna de índice secundaria única:

mysql> select * from demo8 where key2=8888;
+------+------+------+------+-----------+-----------+-----------+--------------+
| id   | key1 | key2 | key3 | key_part1 | key_part2 | key_part3 | common_field |
+------+------+------+------+-----------+-----------+-----------+--------------+
| 8888 | 12   | 8888 | fc9  | 7810      | 1c7ed     | 5d6dbc    | adbea8c      |
+------+------+------+------+-----------+-----------+-----------+--------------+
1 row in set (0.00 sec)

Con base en el conocimiento de artículos anteriores, la ejecución de esta consulta se divide en dos pasos:

  • El primer paso es localizar un registro de índice secundario del índice de árbol B+ correspondiente a idx_key2 según la condición de comparación de equivalencia entre la columna key2 y la constante.
  • En el segundo paso, el registro de usuario completo se obtiene del índice agrupado según el valor de identificación del registro.

Es muy, muy rápido para MySQL ubicar un registro a través de la comparación equivalente entre la clave principal o la columna de índice secundario único y la constante, por lo que se define el método de acceso para ubicar un registro a través de la clave principal o la columna de índice secundario único. como: const , que significa nivel constante, el costo es insignificante.

Sin embargo, este método de acceso constante solo es válido cuando la columna de clave principal o la columna de índice secundario único se compara con una constante para la igualdad.Si la clave principal o el índice secundario único se componen de varias columnas, cada índice en las columnas de índice necesita para ser comparado con constantes para equivalencia, y este método de acceso const es válido (esto se debe a que el único registro puede ubicarse solo si todas las columnas en el índice se comparan para equivalencia).

Para un índice secundario único, el caso de consultar que la columna es un valor NULL es especial:

mysql> select * from demo8 where key2 is null;

La única columna de índice secundario no limita el número de valores NULL, por lo que la declaración anterior puede acceder a varios registros. La declaración anterior no se puede ejecutar utilizando el método de acceso const. En cuanto al método de acceso, hablaremos de ello inmediatamente a continuación.

referencia 2.3

Las columnas de índice secundarias ordinarias se comparan para la igualdad con las constantes:

mysql> select * from demo8 where key1 = 'd9';
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| id    | key1 | key2  | key3 | key_part1 | key_part2 | key_part3 | common_field |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
|    59 | d9   |    59 | b7a  | 041b      | 5b1cf     | e342ac    | e103738      |
|   182 | d9   |   182 | 8bf  | 2b3c      | 08b7c     | a63ed0    | 40f2c52      |
|   401 | d9   |   401 | 137  | adbd      | dafba     | 581313    | ba72bf5      |
|  2114 | d9   |  2114 | d8b  | bf2a      | 117ae     | 69de3d    | f5467a5      |
|  2758 | d9   |  2758 | 2f7  | a159      | e3707     | f60f38    | 795ec06      |
|  3823 | d9   |  3823 | 682  | 347e      | f6195     | 6faa0d    | 5e55f78      |
|  4351 | d9   |  4351 | e92  | f3b4      | a159e     | d3e013    | e28ca48      |
|  5138 | d9   |  5138 | b41  | 1b10      | b9605     | cbe517    | b267144      |
|  5539 | d9   |  5539 | da1  | d30d      | c59b1     | 0c5d79    | ae57b7d      |
|  5604 | d9   |  5604 | ddc  | f0b0      | 00dbf     | f93c0e    | 3218cff      |
|  6050 | d9   |  6050 | 64e  | 22a4      | 69e69     | 7284ba    | 4a5b7d5      |
|  6147 | d9   |  6147 | 529  | cd38      | 71855     | 434168    | a426cbe      |
|  6428 | d9   |  6428 | a38  | c00f      | 9f710     | 9fb7c5    | a722b51      |
|  6456 | d9   |  6456 | eb7  | d208      | 30539     | ee3ae4    | a6c4870      |
|  6473 | d9   |  6473 | c15  | da29      | cc897     | 1e35c3    | 4b5f135      |
|  6860 | d9   |  6860 | b01  | bad8      | 4e3a9     | e83331    | 0cd3b9d      |
|  7257 | d9   |  7257 | fa6  | d537      | a4afe     | bbc5d8    | e11e937      |
|  7333 | d9   |  7333 | a97  | 5532      | 64097     | cb5d16    | 7e43077      |
|  7867 | d9   |  7867 | 3d7  | b341      | 0b0bb     | 7df721    | 8c64142      |
|  8265 | d9   |  8265 | a16  | 120b      | 9d372     | c17ce4    | c481ace      |
|  8371 | d9   |  8371 | 5be  | 7924      | 313f7     | 293487    | cb52072      |
|  8738 | d9   |  8738 | c05  | 7123      | b61b1     | c8d819    | e310cbf      |
|  9005 | d9   |  9005 | 44e  | e857      | 4075c     | 8460a0    | 409cb1d      |
|  9006 | d9   |  9006 | d8c  | 8c2b      | ed54f     | 3b8bfd    | 268fcce      |
|  9362 | d9   |  9362 | 5cb  | 9d70      | 05937     | 1b70d2    | a866a32      |
|  9449 | d9   |  9449 | ab8  | f9c6      | c1917     | 5ffe25    | ff88471      |
| 10146 | d9   | 10146 | 07f  | 31a7      | c30c4     | 7c2e48    | 6c5c562      |
| 10197 | d9   | 10197 | 85a  | 4796      | e5ff9     | d12af4    | 20be699      |
| 10223 | d9   | 10223 | 94b  | c57e      | adfb6     | b93c19    | a7c944b      |
| 10285 | d9   | 10285 | 9ab  | f33d      | 69e5c     | 35a651    | 0953db7      |
| 10621 | d9   | 10621 | a29  | a92b      | fbf80     | 83f1e2    | d167770      |
| 11133 | d9   | 11133 | 560  | 97af      | 35f38     | ceb1b9    | 6e89ca8      |
| 11265 | d9   | 11265 | fcc  | e7d7      | 0243e     | b52571    | 89ea417      |
| 11557 | d9   | 11557 | 1c0  | 7f66      | 0898f     | d41cfc    | e759975      |
| 11614 | d9   | 11614 | de5  | 00f7      | fb3b3     | 93dc1a    | bbe8993      |
| 11672 | d9   | 11672 | f3f  | 9fe4      | da2dd     | 82f711    | 436f3d4      |
| 12477 | d9   | 12477 | d58  | 0613      | 1df6d     | 40999a    | b748cd2      |
| 13789 | d9   | 13789 | 67b  | 5b30      | ab2f3     | 89f0ec    | 9e2d255      |
| 14050 | d9   | 14050 | 537  | bbdc      | 5e87e     | 4ac153    | 0346558      |
| 14363 | d9   | 14363 | 2ac  | 33f3      | e2b82     | 7e55c1    | 45ee579      |
| 14444 | d9   | 14444 | e47  | 6319      | 851b7     | 1d4c57    | e17a95b      |
| 14635 | d9   | 14635 | 16a  | 4d83      | 52b33     | 376017    | c853bc0      |
| 14646 | d9   | 14646 | 202  | 6fdd      | f2486     | 9900f3    | c29d0d6      |
| 15298 | d9   | 15298 | 074  | a7ee      | 6bc1d     | e96458    | 723b0f8      |
| 15489 | d9   | 15489 | 514  | 0bdc      | fb94c     | db5ce8    | 63797e8      |
| 16895 | d9   | 16895 | 4aa  | 921c      | 00b9e     | f07907    | bce779f      |
| 17587 | d9   | 17587 | 6aa  | 621b      | d521f     | a6c5ad    | 45fac89      |
| 18151 | d9   | 18151 | 87d  | cd74      | f7135     | 47d900    | 211303e      |
| 18255 | d9   | 18255 | 4dc  | b9e7      | 99bf2     | 55d0eb    | 3e6ce6c      |
| 18490 | d9   | 18490 | 6a2  | f0ff      | 85e86     | ed9bb8    | dca2cb4      |
| 18872 | d9   | 18872 | 404  | eeee      | 001c7     | 0e846d    | fae0876      |
| 19018 | d9   | 19018 | 142  | 80d7      | 2b9fd     | 77be32    | d6d8398      |
| 19228 | d9   | 19228 | a5b  | a125      | 795fa     | 108159    | 65acbf5      |
| 19537 | d9   | 19537 | 1ca  | 016a      | 3df13     | 3f5b9c    | 720de00      |
| 19940 | d9   | 19940 | 95c  | 6150      | 2696d     | 3f89b8    | d37d43a      |
| 19945 | d9   | 19945 | 538  | 6378      | a20a9     | 2b7b00    | 1865f1c      |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
56 rows in set (0.00 sec)

Los índices secundarios ordinarios no limitan la unicidad de los valores de las columnas de índice, por lo que es posible encontrar múltiples registros correspondientes (como en nuestro ejemplo, se compararon un total de 56 filas que cumplen las condiciones), es decir, el uso de índices secundarios para ejecutar consultas El costo depende de la cantidad de registros de índice secundario que coincidan con el valor equivalente. Si hay menos registros coincidentes, el costo de volver a la tabla sigue siendo relativamente bajo, por lo que MySQL puede optar por usar un índice en lugar de una exploración completa de la tabla para ejecutar la consulta. MySQL considera esta condición de búsqueda como una comparación entre la columna del índice secundario y el valor constante equivalente, y el método de acceso que usa el índice secundario para ejecutar la consulta se llama: ref.
Para un índice secundario ordinario, se pueden hacer coincidir varios registros consecutivos después de la comparación equivalente de la columna de índice, en lugar de hacer coincidir solo un registro como máximo como una clave principal o un índice secundario único, por lo que este método de acceso de referencia es un poco peor que const, pero la eficiencia sigue siendo muy alta cuando el número de registros coincidentes es pequeño en la comparación de los equivalentes del índice secundario (si hay demasiados registros coincidentes del índice secundario, el costo de volver a la tabla será demasiado alto).

Es necesario prestar atención a las siguientes dos situaciones:

  • El caso en el que el valor de la columna del índice secundario es NULL: ya sea un índice secundario común o un índice secundario único, no hay límite para la cantidad de valores NULL contenidos en sus columnas de índice, por lo que usamos la forma clave IS NULL de las condiciones de búsqueda solo pueden usar métodos de acceso de ref como máximo, no métodos de acceso const.
  • Para un índice secundario que contiene múltiples columnas de índice, siempre que la columna de índice continua más a la izquierda sea una comparación equivalente con una constante, se puede usar el método de acceso de referencia.idx_key_part(key_part1, key_part2, key_part3)
mysql> select * from demo8 where key_part1='6378';
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| id    | key1 | key2  | key3 | key_part1 | key_part2 | key_part3 | common_field |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| 19945 | d9   | 19945 | 538  | 6378      | a20a9     | 2b7b00    | 1865f1c      |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
1 row in set (0.00 sec)

mysql> select * from demo8 where key_part1='6378' and key_part2='a20a9';
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| id    | key1 | key2  | key3 | key_part1 | key_part2 | key_part3 | common_field |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| 19945 | d9   | 19945 | 538  | 6378      | a20a9     | 2b7b00    | 1865f1c      |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
1 row in set (0.00 sec)

mysql> select * from demo8 where key_part1='6378' and key_part2='a20a9' and key_part3='2b7b00';
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| id    | key1 | key2  | key3 | key_part1 | key_part2 | key_part3 | common_field |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| 19945 | d9   | 19945 | 538  | 6378      | a20a9     | 2b7b00    | 1865f1c      |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
1 row in set (0.00 sec)
  • Pero si las columnas de índice consecutivas más a la izquierda no son todas comparaciones de igual valor, su método de acceso no se puede llamar ref:
mysql> select * from demo8 where key_part1='6378' and key_part2>'a20a9';
Empty set (0.00 sec)

2.4 ref_or_null

Encuentre los registros cuyo valor de una columna de índice secundario sea igual a una cierta constante, y también desee encontrar los registros cuyo valor sea NULL

mysql> select * from demo8 where key1 = 'd9' or key is null;

Cuando la consulta se ejecuta utilizando un índice secundario en lugar de una exploración completa de la tabla, el método de acceso utilizado por este tipo de consulta se denomina ref_or_null. Es equivalente a encontrar primero dos rangos de registros consecutivos de key1 IS NULL y key1 = 'ef' del árbol B+ correspondiente al índice idx_key1, y luego regresar a la tabla para encontrar registros de usuario completos de acuerdo con los valores de id en estos registros de índice secundario.

rango 2.5

Los varios métodos de acceso presentados anteriormente solo son posibles de usar cuando se compara la columna de índice con un cierto valor constante (ref_or_null es bastante peculiar, y el valor de NULL también se calcula), a veces las condiciones de búsqueda a las que nos enfrentamos son más complejas:

mysql> select * from demo8 where key2 in (5555,6666) or (key2>=1234 and key2<=1235);
+------+------+------+------+-----------+-----------+-----------+--------------+
| id   | key1 | key2 | key3 | key_part1 | key_part2 | key_part3 | common_field |
+------+------+------+------+-----------+-----------+-----------+--------------+
| 1234 | 67   | 1234 | a2d  | 2779      | 18191     | 96a5b2    | 86c5afa      |
| 1235 | 6b   | 1235 | c48  | 43b4      | 0e1d1     | 27f9a0    | 1c17810      |
| 5555 | 0b   | 5555 | dc2  | 6b61      | dac52     | a0451f    | 187011e      |
| 6666 | 00   | 6666 | 9c3  | 99f8      | d22de     | 283e92    | 656f2f1      |
+------+------+------+------+-----------+-----------+-----------+--------------+
4 rows in set (0.00 sec)

Esta consulta se puede ejecutar mediante el escaneo completo de la tabla, pero también se puede ejecutar utilizando el índice secundario + el retorno de la tabla. Si la consulta se ejecuta mediante el índice secundario + el retorno de la tabla, entonces la condición de búsqueda en este momento no solo es necesaria. La columna de índice coincide con el valor equivalente de la constante, pero la columna de índice debe coincidir con un cierto o cierto rango de valores. En esta consulta, siempre que el valor de la columna key2 coincida con cualquiera de los siguientes tres rangos, la coincidencia es exitosa:

  • El valor de key2 es 5555
  • El valor de key2 es 6666
  • El valor de key2 está entre 1234 y 1235

MySQL llama a este método de acceso usando índices para la coincidencia de rangos:range

índice 2.6

mysql> select key_part1,key_part2,key_part3 from demo8  where key_part2 = 'd22de';
+-----------+-----------+-----------+
| key_part1 | key_part2 | key_part3 |
+-----------+-----------+-----------+
| 99f8      | d22de     | 283e92    |
+-----------+-----------+-----------+
1 row in set (0.01 sec)

key_part2 no es la columna de índice más a la izquierda del índice conjunto idx_key_part, por lo que no podemos usar el método de acceso ref o range para ejecutar esta declaración. Pero esta consulta cumple las siguientes dos condiciones:

  • Su lista de consultas tiene solo 3 columnas: key_part1, key_part2, key_part3 y el índice idx_key_part contiene estas tres columnas.
  • Solo hay una columna key_part2 en la condición de búsqueda, esta columna también se incluye en el índice idx_key_part

Puede comparar directamente la condición key_part2 = 'd22de' recorriendo los registros del nodo hoja del índice idx_key_part y agregar los valores de las columnas key_part1, key_part2 y key_part3 de los registros del índice secundario coincidentes correctamente directamente al conjunto de resultados. Dado que los registros de índices secundarios son mucho más pequeños que los registros de índices agrupados (los registros de índices agrupados almacenan todas las columnas definidas por el usuario y las llamadas columnas ocultas, mientras que los registros de índices secundarios solo necesitan almacenar columnas de índice y claves primarias), y este proceso no necesita Ejecutar operaciones de retorno de tabla, por lo que el costo de atravesar directamente el índice secundario es mucho menor que atravesar directamente el índice agrupado.Este método de recorrer los registros del índice secundario se llama:index

2.7 todo

mysql> select * from demo8;

Al igual que esta instrucción SQL, consulte todos los datos. Este método de ejecución de consulta es una exploración de tabla completa. Para una tabla InnoDB, es una exploración directa del índice agrupado. Este método de ejecución de una consulta mediante una exploración de tabla completa se llama: all

3. Asuntos que requieren atención

3.1 Revisar el índice secundario + tabla de retorno

En general, solo se puede usar un único índice secundario para ejecutar consultas, como la siguiente declaración:

mysql> select * from demo8 where key1='00' and key2>15544;

El optimizador de consultas reconocerá dos condiciones de búsqueda en esta consulta

  • clave1='00'
  • clave2>15544

El optimizador generalmente juzga qué condición usar para consultar y escanear menos filas en el índice secundario correspondiente en función de los datos estadísticos de la tabla demo8 y selecciona la condición con menos filas escaneadas para consultar en el índice secundario correspondiente. Luego devuelva los resultados consultados del índice secundario a la tabla para obtener registros de usuario completos y luego filtre los registros de acuerdo con las condiciones restantes de where. Suponiendo que el optimizador decide utilizar el índice idx_key1 para la consulta, todo el proceso de consulta se puede dividir en dos pasos:

  • Paso 1: use el índice secundario para ubicar registros: busque el registro de índice secundario correspondiente del árbol B+ representado por el índice idx_key1 de acuerdo con la condición key1 = '00'
  • Paso 2: Regrese a la tabla de acuerdo con el valor de la clave principal del registro encontrado en el paso anterior, es decir, busque el registro de usuario completo correspondiente en el índice agrupado y luego continúe filtrando el registro de usuario completo de acuerdo con la condición key2 >15544. Devolver los registros que finalmente cumplen con los criterios de filtrado al usuario

Debido a que los registros en los nodos del índice secundario solo contienen columnas de índice y claves principales, solo se usarán las condiciones de búsqueda relacionadas con la columna clave1 cuando se use el índice idx_clave1 para consultar en el paso 1, y las demás condiciones, como clave2 > 9988, están en el paso No se usa en 1. Puede continuar filtrando los registros de usuario completos solo después de que se complete la operación de devolución de tabla en el paso 2.

Tips:
Cabe señalar que aquí de lo que estamos hablando es de la situación general, por lo general solo se utilizará un único índice secundario para ejecutar una consulta

3.2 Aclarar el intervalo de rango utilizado por el método de acceso de rango

Para el índice de árbol B+, siempre que la columna de índice y el uso constante =, <=>, in, not in, sea nulo, no sea nulo, >, <, >=, <=, between, != (no igual a Escrito como <>) o conectado con operadores similares, se puede generar un llamado intervalo.

pista:

  • El operador like es especial y solo puede usar el índice cuando coincide con la cadena completa o con el prefijo de la cadena.
  • El efecto del operador in es el mismo que la conexión entre =varios operadores coincidentes equivalentes, es decir, se generarán múltiples intervalos de un solo punto. Por ejemplo, los efectos de las siguientes dos sentencias son los mismos: select * from demo8 donde clave2 en (1222, 1333); seleccione * de demo8 donde clave2 = 1222 o clave2 = 1333;or

Sin embargo, en el trabajo normal, la cláusula where de una consulta puede tener muchas condiciones de búsqueda pequeñas, y estas condiciones de búsqueda deben conectarse usando los operadores and or or :

  • A y B, tanto A como B son verdaderas, toda la expresión es verdadera
  • A o B, si A o B es verdadero, la expresión completa es verdadera

Cuando queremos usar el método de acceso de rango para ejecutar una declaración de consulta, el punto clave es encontrar los índices disponibles para la consulta y los intervalos de rango correspondientes a estos índices. Veamos cómo extraer el intervalo de rango correcto de las condiciones de búsqueda complejas compuestas por y o o en los siguientes dos casos:

3.2.1 Todas las condiciones de búsqueda pueden usar un índice

mysql> select * from demo8 where key2 > 2222 and key2 > 3333;

Todas las condiciones de búsqueda en esta consulta pueden usar key2, es decir, cada condición de búsqueda corresponde a un intervalo de rango de idx_key2. Estas dos pequeñas condiciones de búsqueda se conectan mediante AND, es decir, se toma la intersección de dos intervalos de rango. La intersección de key2 > 2222 y key2 > 3333 es, por supuesto, key2 > 3333. El rango de la consulta anterior usando idx_key2 es (3333, +∞)

si es o

mysql> select * from demo8 where key2 > 2222 or key2 > 3333;

o significa que se debe tomar la unión de cada intervalo de rango. La unión de key2 > 2222 y key2 > 3333 es key2 > 2222. El intervalo de rango usando idx_key2 en la consulta anterior es (2222, +∞)

3.2.2 Algunas condiciones de búsqueda no pueden usar el índice

mysql> select * from demo8 where key2 > 2222 AND common_field = '039cb00';

El índice que se puede usar en esta instrucción de consulta es solo idx_key2, y el registro del índice secundario de idx_key2 no contiene el campo common_field, por lo que la condición de common_field = '039cb00' no se usa en la etapa de uso del índice secundario. idx_key2 para localizar registros.Esta condición se utiliza después de volver a la tabla para obtener registros de usuario completos, y el intervalo de rango es para el concepto propuesto en el índice para obtener registros, por lo que la condición de common_field = '039cb00' no necesita ser considerado al determinar el intervalo de rango. Cuando determinamos el intervalo de rango para un índice, solo necesitamos reemplazar las condiciones de búsqueda que no usan el índice relevante con verdadero (reemplazar las condiciones de búsqueda que no usan el índice con verdadero, porque no tiene la intención de usar estas condiciones para buscar el índice. Así que ya sea que los registros en el índice cumplan con estas condiciones o no, los seleccionaremos y los usaremos para filtrar cuando regresemos a la tabla más adelante).

mysql> select * from demo8 where key2 > 2222 AND true;

Simplificado

mysql> select * from demo8 where key2 > 2222;

De esto, se puede obtener que el rango de uso de idx_key2 es: (2222, +∞). De la misma forma, la situación de usar o puede obtenerse:

mysql> select * from demo8 where key2 > 2222 or common_field = '039cb00';

mysql> select * from demo8 where key2 > 2222 or true;

mysql> select * from demo8 where true;

Esto también muestra que si se ve obligado a usar idx_key2 para ejecutar la consulta, el rango correspondiente es (-∞, +∞), es decir, debe devolver todos los registros del índice secundario a la tabla. mayor que el escaneo directo de tabla completa. Es decir, si una condición de búsqueda que usa el índice se conecta con una condición de búsqueda que no usa el índice usando o, no se puede usar el índice.

3.2.3 Encuentre el intervalo de coincidencia de rango bajo condiciones de búsqueda complejas

mysql> select * from demo8 
	where (key1 > 'ed' and key2 = 66 ) 
	or (key1 < 'zc' and key1 > 'zz') 
	or (key1 like '%33' and key1 > 'fa' and (key2 < 7777 or common_field = '97d435e')) ;

No entre en pánico cuando vea SQL con condiciones tan complejas, analicémoslo lentamente

Paso 1: primero verifique qué columnas están involucradas en las condiciones de búsqueda en la cláusula where y qué columnas pueden usar índices

Las condiciones de búsqueda de esta consulta involucran las tres columnas de key1, key2 y common_field, y luego la columna key1 tiene un índice secundario común idx_key1, y la columna key2 tiene un índice secundario único idx_key2

Paso 2: Para aquellos índices que pueden usarse, analice sus intervalos de rango

Paso 3: supongamos que usamos idx_key1 para ejecutar la consulta, o usamos el método anterior, eliminamos temporalmente aquellas condiciones de búsqueda que no usan el índice

(key1 > 'ed' and true ) or(key1 < 'zc' and key1 > 'zz') or(true and key1 > 'fa' and (true or true))

seguir simplificando

(key1 > 'ed') OR(key1 < 'zc' AND key1 > 'zz') OR(key1 > 'fa')

Paso 4: Reemplace la condición que siempre es verdadera o falsa

mysql> select 'zc' > 'zz';
+-------------+
| 'zc' > 'zz' |
+-------------+
|           0 |
+-------------+
1 row in set (0.00 sec)

El resultado es 0, que es falso, 'zc' es menor que 'zz'. Coincidencia clave1 < 'zc' Y clave1 > 'zz' siempre es falso, por lo que la condición de búsqueda anterior se puede escribir así:
(key1 > 'ed') OR (key1 > 'fa')

Continuar para simplificar el intervalo

mysql> select 'ed' > 'fa';
+-------------+
| 'ed' > 'fa' |
+-------------+
|           0 |
+-------------+
1 row in set (0.00 sec)

El operador o entre tecla1 > 'ed' y tecla1 > 'fa' se usa para conectar, lo que significa tomar una unión, por lo que el intervalo al que se simplifica el resultado final es: tecla1 > 'ed'. Es decir: si la instrucción de consulta de las condiciones de búsqueda complejas anteriores utiliza el índice idx_key1 para ejecutar la consulta, es necesario extraer todos los registros del índice secundario que satisfagan key1 > 'ed', y luego volver a la tabla con el id de estos registros para obtener un registro de usuario completo y luego usar otros criterios de búsqueda para filtrar.

Paso 5: Suponiendo que usamos idx_key2 para ejecutar la consulta, necesitamos reemplazar temporalmente aquellas condiciones de búsqueda que no usan el índice con la condición trueE, y las condiciones de búsqueda relacionadas con key1 y common_field deben ser reemplazadas

(true and key2 = 66 ) or(true and true) or(true and true and (key2 < 7777 or true))

El resultado de clave2 < 7777 O verdadero es verdadero, continúe simplificando

key2 = 66 or true

Continuar simplificando: verdadero

Este resultado significa que si queremos usar el índice idx_key2 para ejecutar la instrucción de consulta, debemos escanear todos los registros del índice secundario idx_key2 y luego volver a la tabla.En comparación con el uso del índice secundario idx_key1, la ganancia supera la ganancia. , y los resultados de la comparación de los dos métodos no se utilizarán en el índice idx_key2.

4. Fusión de índice

En MySQL, muchas funciones de optimización están incorporadas oficialmente para nosotros. Ya sea que necesitemos habilitarlas o no, es necesario que las configuremos manualmente:

mysql> show variables like 'optimizer_switch'\g
*************************** 1. row ***************************
variable_name: optimizer_switch
        value: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on
1 row in set (0.01 sec)

Expliquemos brevemente:

  • index_merge=on (fusión de índice)
  • index_merge_union=on (Fusión de índice de unión—unión de valores de id obtenidos por índices no agrupados)
  • index_merge_sort_union=on (Combinación de índice Sort-Union - el valor de identificación obtenido por el índice no agrupado se ordena primero - toma la unión)
  • index_merge_intersection=on (Fusión de índice de intersección: la intersección de los valores de identificación obtenidos por índices no agrupados)
  • engine_condition_pushdown=on (empuje hacia abajo de la condición del motor: solo se usa para el motor NDB, cuando está habilitado, los datos filtrados de acuerdo con la condición DONDE se envían al nodo SQL para su procesamiento, y los datos de todos los nodos de datos no están habilitados para enviarse al SQL nodo de procesamiento).
  • index_condition_pushdown=on (empuje hacia abajo de la condición del índice: ICP)
  • mrr=on (Multi-Range Read-MRR—el objetivo principal de esta optimización es usar la lectura de disco secuencial tanto como sea posible)
  • mrr_cost_based=on (elección basada en el costo, si el cálculo se basa en el cálculo del costo/consumo de juicio usando MRR)
  • block_nested_loop=on (unión de bucle anidado basada en bloques - BNL)
  • batched_key_access=off (BKA: optimización para el algoritmo Index Nested-Loop Join (NLJ))
  • materialización=en (materialización)
  • subquery_materialization_cost_based=on (si habilitar el cálculo del costo de la materialización de la subconsulta)
  • semijoin=on (semijoin)
  • loosescan=on (semi-join - escaneo suelto)
  • firstmatch=on (semi unión - primera coincidencia)
  • duplicateweedout=on (semi-unión - eliminación de valores duplicados)
  • use_index_extensions=on (usar extensiones de índice)
  • condition_fanout_filter=on (filtrado condicional (fanout))
  • derivado_merge=on (ver/fusión de tabla derivada, necesita cooperar con Auto_key)

Estas funciones de optimización se implementarán lentamente en detalle en artículos posteriores.Volviendo al contenido de hoy, dijimos anteriormente que MySQL solo usa un único índice secundario como máximo cuando ejecuta una consulta en circunstancias normales, pero en algunos casos especiales también es posible use múltiples índices secundarios en una consulta. MySQL llama a este método de ejecución de usar múltiples índices para completar una consulta: combinación de índice, que es la función de optimización que se ubica en la parte superior. Específicamente, hay tres tipos de algoritmos de combinación de índice:

4.1 Fusión de intersección

La traducción literal de Intersección es intersección. Esto significa que una determinada consulta puede usar varios índices secundarios y los resultados consultados desde varios índices secundarios se cruzarán.

mysql> select * from demo8 where key1='4a' AND key3='c84';

Si esta consulta se ejecuta mediante fusión de intersección, el proceso es el siguiente:

  • Saque el registro relacionado de key1 = '4a' del árbol B+ correspondiente al índice secundario idx_key1.
  • Extraiga los registros relevantes de key3 = 'c84' del árbol B+ correspondiente al índice secundario idx_key3.
  • Los registros del índice secundario se componen de columna de índice + clave principal, por lo que podemos calcular la intersección de los valores de id en los dos conjuntos de resultados.
  • Regrese a la tabla de acuerdo con la lista de valores de identificación generada en el paso anterior, es decir, extraiga el registro de usuario completo con el valor de identificación especificado del índice agrupado y devuélvalo al usuario.

Algunos estudiantes aquí pensarán: ¿Por qué no usar idx_key1 o idx_key3 directamente para leer un índice secundario basado en una determinada condición de búsqueda y luego filtrar otra condición de búsqueda después de regresar a la tabla? Aquí hay un análisis del costo entre los dos métodos de ejecución de consultas:

El costo de leer solo un índice secundario:

  • Leer un índice secundario según una determinada condición de búsqueda;
  • Regrese a la tabla de acuerdo con el valor de la clave principal obtenido del índice secundario y luego filtre otras condiciones de búsqueda;

Tome el costo de la intersección después de leer múltiples índices secundarios:

  • Leer diferentes índices secundarios según diferentes condiciones de búsqueda;
  • Tome la intersección de los valores de clave principal obtenidos de múltiples índices secundarios y luego regrese a la tabla;

Aunque leer varios índices secundarios consume más rendimiento que leer un índice secundario, la operación de lectura de índices secundarios es E/S secuencial, mientras que la operación de volver a la tabla es E/S aleatoria, por lo que si solo se lee un índice secundario al indexar , la cantidad de registros que deben devolverse a la tabla es muy grande y la cantidad de registros que se cruzan después de leer varios índices secundarios es muy pequeña. Cuando la pérdida de rendimiento causada por volver a la tabla se guarda en comparación con el rendimiento generado por el acceso a múltiples índices secundarios Cuando la pérdida es mayor, es más barato leer la intersección de múltiples índices secundarios que leer solo un índice secundario.

MySQL solo puede usar la combinación de índices de intersección en ciertas situaciones específicas:

Situación 1: la columna del índice secundario es una coincidencia de equivalencia. Para un índice conjunto, cada columna del índice conjunto debe ser una coincidencia de equivalencia y solo una parte de las columnas no puede coincidir.

Por ejemplo, la siguiente consulta puede usar los dos índices secundarios idx_key1 y idx_key_part para realizar la operación de fusión de índices de intersección:

mysql> select * from demo8 where key1 = 'a' and key_part1 = 'a' and key_part2 = 'b' and key_part3 = 'c';

Las siguientes dos consultas no se pueden fusionar con índices de intersección:

mysql> select * from demo8 where key1 > 'a' and key_part1 = 'a' and key_part2 = 'b' and key_part3 = 'c';
mysql> select * from demo8 where key1 = 'a' and key_part1 = 'a';

La primera consulta se debe a que la coincidencia de rango se realiza en key1 y la segunda consulta se debe a que la columna key_part2 en el índice conjunto idx_key_part no aparece en las condiciones de búsqueda, por lo que estas dos consultas no se pueden fusionar con el índice Intersection.

Caso 2: la columna de clave principal puede ser una coincidencia de rango.

Por ejemplo, la siguiente consulta puede usar la clave principal y idx_key1 para fusionar el índice de intersección:

mysql> select * from demo8 where id > 100 and key1 = 'a';

Para el índice secundario de InnoDB, los registros se ordenan primero según la columna del índice. Si el índice secundario es un índice conjunto, se ordenará según las columnas del índice conjunto. El registro de usuario del índice secundario se compone de columna de índice + clave principal. Puede haber muchos registros con el mismo valor de la columna de índice secundario, y los registros con el mismo valor de estas columnas de índice se ordenan de acuerdo con el valor de la Clave primaria. La combinación de índices de intersección solo es posible cuando las columnas del índice secundario son todas coincidencias equivalentes, porque solo en este caso el conjunto de resultados consultado en función del índice secundario se ordena según el valor de la clave principal.

¿entonces? Todavía no entiendo que el conjunto de resultados consultado en función del índice secundario se ordena según el valor de la clave principal. ¿Cuál es el beneficio de usar el índice de intersección para fusionar? Muchacho, no olvide que la fusión del índice de intersección intersectará los valores de clave principal consultados desde múltiples índices secundarios.Si el conjunto de resultados consultado desde cada índice secundario ya está ordenado de acuerdo con la clave principal, entonces el proceso de encontrar la intersección es muy fácil. Supongamos que una consulta utiliza la combinación de índices de intersección para obtener los valores de clave principal de los dos índices secundarios idx_key1 y idx_key2 respectivamente:

  • Obtenga los valores de clave principal ordenados de idx_key1: 1, 3, 5
  • Obtenga los valores de clave principal ordenados de idx_key2: 2, 3, 4

Luego, el proceso de encontrar la intersección es así: saque el valor de la clave primaria más pequeña en los dos conjuntos de resultados uno por uno, si los dos valores son iguales, agréguelo al resultado de la intersección final, de lo contrario, descarte la clave primaria más pequeña actual valor de la clave principal y, a continuación, tome el valor descartado Compare el último valor de la clave principal del conjunto de resultados donde se encuentra el valor de la clave principal hasta que se agote el valor de la clave principal en un determinado conjunto de resultados. leer:

  • Primero, saque el valor de clave principal más pequeño de los dos conjuntos de resultados para comparar, porque 1 < 2, así que descarte el valor de clave principal 1 del conjunto de resultados de idx_key1 y saque los últimos 3 para comparar.
  • Debido a que 3 > 2, el valor de clave principal 2 del conjunto de resultados de idx_key2 se descarta y el último 3 se elimina para comparar.
  • Debido a que 3 = 3, agregue 3 al resultado final de la intersección y continúe comparando los valores de clave principal detrás de los dos conjuntos de resultados.
  • Los siguientes valores de clave principal tampoco son iguales, por lo que solo el valor de clave principal 3 se incluye en el resultado final de la intersección.

A pesar de la complejidad de lo que escribimos, de hecho, este proceso es realmente muy rápido y la complejidad de tiempo es O(n), pero si el conjunto de resultados consultado de cada índice secundario no está ordenado por la clave principal, entonces el resultado debe primero ser Después de ordenar los valores de clave principal centralizados, llevará mucho tiempo realizar el proceso anterior.

Sugerencia:
existe un término adecuado para recuperar registros de la tabla de acuerdo con el valor de la clave primaria ordenada, llamado: Recuperación ordenada de filas, o ROR para abreviar, y estará familiarizado con este término cuando lo vea en algunos lugares en el futuro. .

Además, no solo se puede utilizar la combinación de índices de intersección entre varios índices secundarios, sino que el índice de clúster también puede participar en la combinación de índices.Use la
combinación de índices de intersección. ¿Por qué la clave principal puede coincidir con el rango? Todavía tengo que volver al escenario de la aplicación, por ejemplo, mire la consulta a continuación:

mysql> select * from demo8 where key1 = 'a' and id > 100;

Suponiendo que esta consulta se puede fusionar utilizando el índice de intersección, damos por sentado que esta consulta obtendrá algunos registros del índice agrupado de acuerdo con la condición de id > 100, y obtendrá algunos registros del índice secundario idx_key1 a través de la condición de key1 = 'a' , y luego encuentre la intersección. De hecho, esto complica el problema, y ​​no hay necesidad de obtener un registro del índice agrupado. No olvide que todos los registros del índice secundario tienen valores de clave principal, por lo que puede ejecutar directamente el filtro de condición id > 100 en el valor de clave principal obtenido de idx_key1, es muy simple. Por lo tanto, la condición de búsqueda que involucra la clave principal es solo para
filtrar registros del conjunto de resultados obtenidos de otros índices secundarios, y no es importante si se trata de una coincidencia equivalente o no.

Por supuesto, los casos 1 y 2 mencionados anteriormente son solo condiciones necesarias para que se produzca la fusión del índice de intersección, pero no condiciones suficientes. Incluso si el Caso 1 y el Caso 2 son verdaderos, la fusión del índice de intersección puede no ocurrir necesariamente y, en última instancia, depende de cómo elija el optimizador. El optimizador usará la combinación de índice de intersección solo cuando la cantidad de registros obtenidos de un índice secundario basado solo en las condiciones de búsqueda sea demasiado grande, lo que resultará en un costo demasiado alto para volver a la tabla y la cantidad de registros que deben devolverse. a la tabla después de la fusión a través del índice de intersección se reduce considerablemente.

4.2 Fusión sindical

Cuando escribimos una declaración de consulta, a menudo queremos eliminar los registros que cumplen con una determinada condición de búsqueda y también eliminar los registros que cumplen con otra condición de búsqueda. Decimos que existe una relación OR entre estas diferentes condiciones de búsqueda. A veces, diferentes condiciones de búsqueda de la relación OR utilizan índices diferentes, por ejemplo:

mysql> select * from demo8 where key1 < 'a' or key3 > 'z';

Intersección significa intersección, que es aplicable al caso en que las condiciones de búsqueda que utilizan diferentes índices están conectadas por y; Unión es el significado de unión, que es aplicable al caso en que las condiciones de búsqueda que utilizan diferentes índices están conectadas por o. Similar a la fusión de índices de intersección, MySQL solo puede usar la fusión de índices de unión bajo ciertas circunstancias:

Situación 1: Las columnas del índice secundario son coincidencias de equivalencia. Para el índice conjunto, cada columna del índice conjunto debe tener coincidencias de equivalencia y solo algunas de las columnas coincidentes no pueden aparecer.

Por ejemplo, la consulta a continuación puede usar dos índices secundarios, idx_key1 y idx_key_part, para fusionar índices de unión:

mysql> select * from demo8 where key1 = 'a' or ( key_part1 = 'a' and key_part2 = 'b' and key_part3 = 'c');

Sin embargo, las siguientes dos consultas no se pueden fusionar con índices de unión:

mysql> select * from demo8 where key1 > 'a' or (key_part1 = 'a' and key_part2 = 'b' and key_part3 = 'c');
mysql> select * from demo8 where key1 = 'a' or key_part1 = 'a';

La primera consulta se debe a que la coincidencia de rango se realiza en key1 y la segunda consulta se debe a que la columna key_part2 en el índice conjunto idx_key_part no aparece en las condiciones de búsqueda, por lo que estas dos consultas no se pueden fusionar con el índice de unión.
Caso 2: la columna de clave principal puede ser una coincidencia de rango.
Caso 3: use la condición de búsqueda fusionada por el índice de intersección (esta situación es bastante fácil de entender, es decir, algunas partes de la condición de búsqueda usan la intersección del conjunto de claves primarias obtenido al fusionar el índice de intersección y el conjunto de claves primarias obtenido por otros métodos).

En realidad, esta situación es bastante fácil de entender, es decir, algunas partes de la condición de búsqueda utilizan la Intersectionintersección del conjunto de claves principales obtenido mediante la combinación de índices y el conjunto de claves principales obtenido mediante otros métodos, como esta consulta:

mysql> select * from single_table where key_part1 = 'a' and key_part2 = 'b' and key_part3 = 'c' or (key1 = 'a' and key3 = 'b');

El optimizador podría ejecutar esta consulta de esta manera:

  • En primer lugar, según la condición de búsqueda clave1 = 'a' Y clave3 = 'b', el conjunto de claves principales se obtiene fusionando los índices idx_clave1 e idx_clave3 mediante el índice de intersección.
  • Luego, de acuerdo con la condición de búsqueda key_part1 = 'a' AND key_part2 = 'b' AND key_part3 = 'c' obtenga otro conjunto de claves principales del índice conjunto idx_key_part.
  • Combine los dos conjuntos de claves principales anteriores mediante la combinación de índices de unión, y luego regrese a la tabla y devuelva el resultado al usuario

Por supuesto, si las condiciones de consulta cumplen con estas condiciones, la combinación de índices de unión no necesariamente se adoptará. Al final, todavía depende de cómo elija el optimizador. El optimizador utilizará la combinación de índices de unión solo cuando la cantidad de registros obtenidos de un índice secundario basado solo en las condiciones de búsqueda sea relativamente pequeña y el costo de acceso a través de la combinación de índices de unión sea menor que el de la exploración de tabla completa.

4.3 Fusión de clasificación-unión

Las condiciones de uso de la fusión del índice de la Unión son demasiado estrictas y es necesario garantizar que cada columna del índice secundario se pueda utilizar bajo la condición de coincidencia equivalente. Por ejemplo, la siguiente consulta no puede usar la combinación de índices de unión:

mysql> select * from demo8 where key1 < 'a' and key3 > 'z';

Esto se debe a que los valores de la clave principal de los registros del índice secundario obtenidos del índice idx_key1 según la clave1 < 'a' no están ordenados, y los valores de la clave principal de los registros del índice secundario obtenidos del índice idx_key3 según la clave3 > 'z' Los valores clave no están ordenados, pero las dos condiciones de key1 < 'a' y key3 > 'z' son particularmente tentadoras para nosotros, por lo que podemos hacer esto:

  • Primero obtenga registros del índice secundario idx_key1 según la condición key1 < 'a', y clasifíquelos según el valor de la clave principal de los registros
  • Según la condición key3 > 'z', los registros siempre se obtienen del índice secundario idx_key3 y se ordenan según el valor de la clave principal de los registros.
  • Debido a que los valores de la clave principal de los dos índices secundarios anteriores están ordenados, las operaciones restantes son las mismas que el método de fusión del índice Union

Primero ordenamos lo anterior de acuerdo con los valores de la clave principal registrados en el índice secundario, y luego lo ejecutamos de acuerdo con el método de combinación de índice de unión, que se llama combinación de índice de clasificación-unión. es un paso más que la simple combinación de índice de unión El proceso de ordenar los valores de clave principal de los registros de índice secundario.

Sugerencia: ¿
Por qué no hay una combinación de índice de clasificación-intersección cuando hay una combinación de índice de clasificación-unión? Sí, de hecho, no existe tal cosa como la fusión del índice Sort-Intersection. El escenario aplicable de Sort-Union es que la cantidad de registros obtenidos de un índice secundario basado solo en los criterios de búsqueda es relativamente pequeña, por lo que el costo de ordenar estos registros de índice secundario según el valor de la clave principal no es demasiado alto. El escenario aplicable para fusionar el índice de intersección es que se obtienen demasiados registros de un índice secundario basado únicamente en los criterios de búsqueda, lo que resulta en una sobrecarga excesiva para regresar a la tabla. Después de la fusión, la sobrecarga para regresar a la tabla puede ser significativamente reducido, pero si se agrega Sort-Intersection, es necesario ordenar una gran cantidad de registros de índice secundario de acuerdo con el valor de la clave principal. Este costo puede ser mayor que el de volver a consultar la tabla, por lo que no se introduce Sort-Intersection .

4.4 Notas sobre la fusión de índices conjuntos

Índice conjunto en lugar de fusión de índice de intersección

mysql> select * from demo8 where key1 = 'a' and key3 = 'b';

La razón por la que esta consulta se puede ejecutar combinando el índice de intersección no es porque idx_key1 e idx_key3 sean dos índices de árbol B+ separados. Si crea un índice conjunto para estas dos columnas, use este índice conjunto directamente para hacer las cosas. Ahora, ¿Por qué molestarse en fusionarse con cualquier índice, así:

mysql> alter table demo8 drop index idx_key1, idx_key3, add index idx_key1_key3(key1, key3);

De esta manera, nos deshacemos de los inútiles idx_key1 e idx_key3, y luego agregamos un índice conjunto idx_key1_key3. Usar este índice conjunto para consultar es simplemente rápido y bueno. No hay necesidad de leer un árbol B+ adicional o fusionar los resultados. ¿Por qué? no para?

Sugerencia:
Pero tenga cuidado de que hay escenarios comerciales en los que la columna key3 se consulta por separado, por lo que debe agregar el índice separado de la columna key3

Resumir

Hoy, aprendí sobre el método de acceso de MySQL para una sola tabla y la combinación de características e índices de optimización. Resumámoslo a continuación:

  • Método de acceso para una sola tabla:

    • const: El método de acceso para localizar un registro a través de la clave primaria o la columna de índice secundario único se define como: const, que significa nivel constante, y el costo es despreciable.
    • ref: La condición de búsqueda es comparar el valor equivalente de la columna del índice secundario con una constante.El método de acceso que utiliza el índice secundario para ejecutar la consulta se denomina: ref.
    • ref_or_null: Cuando la consulta se ejecuta utilizando un índice secundario en lugar de un escaneo completo de la tabla, el método de acceso utilizado por este tipo de consulta se llama: ref_or_null.
    • rango: El método de acceso que utiliza el índice para la comparación de rangos se llama: rango.
    • index: El método de ejecución para atravesar registros de índice secundario se llama: index.
    • all: El método de ejecutar una consulta usando un escaneo completo de la tabla se llama: all.
  • Tres algoritmos para la combinación de índices:

    • Fusión de intersección (index_merge_intersection).
    • Fusión de unión (index_merge_union).
    • Fusión de clasificación-unión (index_merge_sort_union).

También hemos aprendido que las condiciones de activación de los tres algoritmos para la fusión de índices son necesarias e insuficientes. Si los algoritmos relevantes se utilizarán al final, aún debe ser juzgado por el optimizador. Al mismo tiempo, también aprendí el intervalo de rango utilizado por el método de acceso de rango y estimé el costo de ejecutar SQL usando diferentes índices mediante análisis artificial. El contenido de hoy tiene más principios, pero es muy simple de entender. Debe combinar el conocimiento previo del índice de árbol MySQL B+ para sentir la sutileza del diseño de MySQL.

Hasta ahora, el estudio de hoy ha terminado, espero que te conviertas en un yo indestructible
~~~

No puedes conectar los puntos mirando hacia adelante; solo puedes conectarlos mirando hacia atrás. Así que tienes que confiar en que los puntos se conectarán de alguna manera en tu futuro. Tienes que confiar en algo: tu instinto, destino, vida, karma, lo que sea. Este enfoque nunca me ha defraudado y ha marcado una gran diferencia en mi vida.

Si mi contenido te es útil, por favor 点赞, 评论,, 收藏la creación no es fácil, el apoyo de todos es la motivación para que yo persevere

inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/liang921119/article/details/130707882
Recomendado
Clasificación