[Análisis] del principio MySQL Explicar y análisis en profundidad de seguimiento del principio de toda la investigación vaya índice difusa

I. Antecedentes

Hoy en día, el estudiante un grupo de intercambio planteó una pregunta. Look:
Aquí Insertar imagen Descripción
Después, los estudiantes realmente han hecho una investigación completa tomando el índice de ejemplo difusa:
Aquí Insertar imagen Descripción
a esto podemos ver que estos dos sql mayor diferencia es: una consulta de campo completo (select *), pero sólo una consultar la clave principal (seleccione ID).

En este punto, hay otros estudiantes hablado de otros programas:
Aquí Insertar imagen Descripción
Indización de texto completo no hace falta decirlo, que hacen que toda la investigación vaya índice difusa. Pero el índice que cubre este programa, creo que es consistente con el fondo:

1, debido a que el fondo está la cuestión del campo de consulta difusa es el índice normal, mientras que el índice general sólo consulta la clave primaria puede pasar un índice de cobertura.

2, y el fondo, es decir, solamente la consulta de clave principal (ID) está representada pasar indexado.

En segundo lugar, la preparación de datos y reproducir la escena

1, mesas de preparación y datos:

Crear una tabla de usuario, agregar un campo de índice de teléfono normal:

CREATE TABLE `user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `phone` varchar(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_phone` (`phone`) USING BTREE COMMENT 'phone索引'
) ENGINE=InnoDB AUTO_INCREMENT=200007 DEFAULT CHARSET=utf8;

100 000 Preparación de datos significado de significado:

delimiter ;
CREATE DEFINER=`root`@`localhost` PROCEDURE `iniData`()
begin
  declare i int;
  set i=1;
  while(i<=100000)do
    insert into user(name,age,phone) values('测试', i, 15627230000+i);
    set i=i+1;
  end while;
end;;
delimiter ;

call iniData();

2, la implementación de SQL, ver el plan de ejecución:

explain select * from user where phone like '%156%';
explain select id from user where phone like '%156%';

3. Los resultados:

carné de identidad seleccione tipo mesa particiones tipo possible_keys llave key_len árbitro filas filtrado Extra
1 SENCILLO usuario TODOS 99927 11.11 utilizando, cuando
carné de identidad seleccione tipo mesa particiones tipo possible_keys llave key_len árbitro filas filtrado Extra
1 SENCILLO usuario índice index_phone 36 99927 11.11 Usando donde; utilizando el índice

Podemos ver que el segundo SQL muestran, de hecho estaban usando index_phoneel índice.

Pero el estudiante cuidadoso puede encontrar: possible_keysen realidad está vacía! La transmisión de la enfermedad. . .

Estoy aquí para hablar de las relaciones y prossible_keys clave:

1, possible_keysel índice puede ser utilizado, y keyes el índice de uso real;

2, el es normal: keyíndice incluyen inevitablemente en possible_keysel.

Hay un pequeño truco: con el índice y el número de líneas sin utilizar un índice de lectura (filas) resultó ser el mismo!

En tercer lugar, la etapa de verificación y conjeturas

Se mencionó anteriormente, possible_keysy keyla relación, entonces usamos la toma normal, el índice de verificarla.

El siguiente código SQL, no todas consulta difusa, pero la consulta difusa derecho, garantizado para estar seguro de tener el índice, que se ven por separado en este momento possible_keysy keyvalores:

explain select id from user where phone like '156%';

Los resultados:

carné de identidad seleccione tipo mesa particiones tipo possible_keys llave key_len árbitro filas filtrado Extra
1 SENCILLO usuario rango index_phone index_phone 36 49963 100 Usando donde; utilizando el índice

Aquí también obvia:

1, possible_keysdonde no incluyen keyen el índice.

2, y rowsal instante se redujo a 49.963, por un total duplicó y filteredllegó a 100.

Etapa conjetura:

1, en primer lugar, select id from user where phone like '%156%';debido a que el índice de cobertura y no gastar el índice index_phone.

2, possible_keys es nula, demostrado ningún acceso al índice para encontrar el árbol. Obviamente, select id from user where phone like '%156%';aunque la pantalla es el índice se ha ido, pero lee el número de filas filas y select * from user where phone like '%156%';no tomaron el índice de filas es el mismo.

3, entonces podemos suponer, select id from user where phone like '%156%';aun cuando los índices que cubren estaban usando index_phoneel índice, pero no pudieron encontrar un árbol para pasar, sólo el orden normal de recorrer el árbol de índice. Así que, de hecho, dos pequeñas mesas en el campo SQL, el rendimiento de las consultas deben ser armó de valor.

En cuarto lugar, verificado por análisis de trazas

Estábamos usando el análisis de seguimiento para SQL Optimizer es cómo elegir.

1, todo el campo de la investigación:
-- 开启优化器跟踪
set session optimizer_trace='enabled=on';
select * from user where phone like '%156%';
-- 查看优化器追踪
select * from information_schema.optimizer_trace;

Aquí nos fijamos en TRACE en la línea:

{
  "steps": [
    {
      "join_preparation": {
        "select#": 1,
        "steps": [
          {
            "expanded_query": "/* select#1 */ select `user`.`id` AS `id`,`user`.`name` AS `name`,`user`.`age` AS `age`,`user`.`phone` AS `phone` from `user` where (`user`.`phone` like '%156%')"
          }
        ]
      }
    },
    {
      "join_optimization": {
        "select#": 1,
        "steps": [
          {
            "condition_processing": {
              "condition": "WHERE",
              "original_condition": "(`user`.`phone` like '%156%')",
              "steps": [
                {
                  "transformation": "equality_propagation",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                },
                {
                  "transformation": "constant_propagation",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                },
                {
                  "transformation": "trivial_condition_removal",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                }
              ]
            }
          },
          {
            "substitute_generated_columns": {
            }
          },
          {
            "table_dependencies": [
              {
                "table": "`user`",
                "row_may_be_null": false,
                "map_bit": 0,
                "depends_on_map_bits": [
                ]
              }
            ]
          },
          {
            "ref_optimizer_key_uses": [
            ]
          },
          {
            "rows_estimation": [
              {
                "table": "`user`",
                "table_scan": {
                  "rows": 99927,
                  "cost": 289
                }
              }
            ]
          },
          {
            "considered_execution_plans": [
              {
                "plan_prefix": [
                ],
                "table": "`user`",
                "best_access_path": {
                  "considered_access_paths": [
                    {
                      "rows_to_scan": 99927,
                      "access_type": "scan", // 顺序扫描
                      "resulting_rows": 99927,
                      "cost": 20274,
                      "chosen": true
                    }
                  ]
                },
                "condition_filtering_pct": 100,
                "rows_for_plan": 99927,
                "cost_for_plan": 20274,
                "chosen": true
              }
            ]
          },
          {
            "attaching_conditions_to_tables": {
              "original_condition": "(`user`.`phone` like '%156%')",
              "attached_conditions_computation": [
              ],
              "attached_conditions_summary": [
                {
                  "table": "`user`",
                  "attached": "(`user`.`phone` like '%156%')"
                }
              ]
            }
          },
          {
            "refine_plan": [
              {
                "table": "`user`"
              }
            ]
          }
        ]
      }
    },
    {
      "join_execution": {
        "select#": 1,
        "steps": [
        ]
      }
    }
  ]
}
2, sólo la consulta de clave principal
set session optimizer_trace='enabled=on';
select id from user where phone like '%156%';
-- 查看优化器追踪
select * from information_schema.optimizer_trace;

Aquí seguimos mirando TRACE en la línea:

{
  "steps": [
    {
      "join_preparation": {
        "select#": 1,
        "steps": [
          {
            "expanded_query": "/* select#1 */ select `user`.`id` AS `id` from `user` where (`user`.`phone` like '%156%')"
          }
        ]
      }
    },
    {
      "join_optimization": {
        "select#": 1,
        "steps": [
          {
            "condition_processing": {
              "condition": "WHERE",
              "original_condition": "(`user`.`phone` like '%156%')",
              "steps": [
                {
                  "transformation": "equality_propagation",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                },
                {
                  "transformation": "constant_propagation",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                },
                {
                  "transformation": "trivial_condition_removal",
                  "resulting_condition": "(`user`.`phone` like '%156%')"
                }
              ]
            }
          },
          {
            "substitute_generated_columns": {
            }
          },
          {
            "table_dependencies": [
              {
                "table": "`user`",
                "row_may_be_null": false,
                "map_bit": 0,
                "depends_on_map_bits": [
                ]
              }
            ]
          },
          {
            "ref_optimizer_key_uses": [
            ]
          },
          {
            "rows_estimation": [
              {
                "table": "`user`",
                "table_scan": {
                  "rows": 99927,
                  "cost": 289
                }
              }
            ]
          },
          {
            "considered_execution_plans": [
              {
                "plan_prefix": [
                ],
                "table": "`user`",
                "best_access_path": {
                  "considered_access_paths": [
                    {
                      "rows_to_scan": 99927,
                      "access_type": "scan", // 顺序扫描
                      "resulting_rows": 99927,
                      "cost": 20274,
                      "chosen": true
                    }
                  ]
                },
                "condition_filtering_pct": 100,
                "rows_for_plan": 99927,
                "cost_for_plan": 20274,
                "chosen": true
              }
            ]
          },
          {
            "attaching_conditions_to_tables": {
              "original_condition": "(`user`.`phone` like '%156%')",
              "attached_conditions_computation": [
              ],
              "attached_conditions_summary": [
                {
                  "table": "`user`",
                  "attached": "(`user`.`phone` like '%156%')"
                }
              ]
            }
          },
          {
            "refine_plan": [
              {
                "table": "`user`"
              }
            ]
          }
        ]
      }
    },
    {
      "join_execution": {
        "select#": 1,
        "steps": [
        ]
      }
    }
  ]
}

Bueno, aquí podemos encontrar, analizar dentro de la traza, no mostraron la elección real de lo que el índice de optimizador para SQL, pero esto demuestra que estamos usando una exploración secuencial método para encontrar los datos.

Probablemente, la única diferencia es que: una tabla de análisis completo utilizando el índice de clave principal, mientras que la otra es usar un índice ordinario escaneo completo de tabla, pero los dos no pasó el árbol de encontrar, que es inútil en las características de la B + Árbol para mejorar el rendimiento de consulta.

En sexto lugar, la conclusión

1, cuando la consulta SQL completo solamente difuso conjunto de resultados de consulta como clave principal, debido a que el índice de la cubierta, el índice gastará campo de consulta correspondiente.

2, incluso si el índice estaban usando, pero no pudo encontrar un árbol para pasar características, pero el orden normal de recorrido.

3, mientras que el escaneo completo de tabla normal es el índice de clave principal de la orden de recorrido, por lo que, de hecho, el rendimiento de ambos es en realidad el mismo.

Supongo que te gusta

Origin www.cnblogs.com/Howinfun/p/12449975.html
Recomendado
Clasificación