[Analysis] of the principle MySQL Explain & Trace depth analysis of the principle of the whole inquiry go fuzzy index

I. Background

Today, the exchange group one student raised a question. Look:
Here Insert Picture Description
After, the students really have made a full inquiry taking the index of fuzzy example:
Here Insert Picture Description
to this we can see that these two sql biggest difference is: a full-field query (select *), but only a query primary key (select id).

At this point, there are other students talked about other programs:
Here Insert Picture Description
full-text indexing This goes without saying, that make the whole inquiry go fuzzy index. But the index covering this program, I think that is consistent with the background:

1, because the background is the question of fuzzy query field is normal index, while the general index only queries the primary key can spend a covering index.

2, and the background, that is, only the primary key query (ID) displayed spend indexed.

Second, the data preparation and reproduce the scene

1, preparation tables and data:

Create a user table, add a field to ordinary phone index:

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 Data Preparation meaning of meaning:

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, the implementation of SQL, view the execution plan:

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

3. The results:

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE user ALL 99927 11.11 Using where
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE user index index_phone 36 99927 11.11 Using where; Using index

We can see that the second SQL indeed show were using index_phonethe index.

But the careful student may find: possible_keysactually is empty! Transmission of the disease. . .

I am here to talk about the relationship prossible_keys and key:

1, possible_keysthe index may be used, and keyis the index of actual use;

2, the normal is: keyindex inevitably included in possible_keysthe.

There is a little trick: using the index and the number of lines without using an index reading (rows) turned out to be the same!

Third, the verification stage and conjecture

Mentioned above, possible_keysand keythe relationship, then we use the normal taking the index to verify it.

The following SQL, not all fuzzy query, but the right fuzzy query, guaranteed to be certain of taking the index, we look separately at this time possible_keysand keyvalues:

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

Results of the:

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE user range index_phone index_phone 36 49963 100 Using where; Using index

Here too obvious:

1, possible_keyswhere it does include keyin the index.

2, and rowsinstantly dropped to 49,963, down a full doubled and filteredreached 100.

Stage guess:

1, first of all, select id from user where phone like '%156%';because the covering index rather spend the index index_phone.

2, possible_keys is null, proved no access to the index to find the tree. Obviously, select id from user where phone like '%156%';even though the display is gone index, but read the number of rows rows and select * from user where phone like '%156%';did not take the index of rows is the same.

3, then we can guess, select id from user where phone like '%156%';even as covering indexes were using index_phonethe index, but failed to find a tree to spend, just the normal order of traversing the index tree. So, in fact, two small tables in the SQL field, the query performance should be summoned up the courage.

Fourth, verified by Trace Analysis

We were using the Trace analysis for both SQL optimizer is how to choose.

1, the whole field of inquiry:
-- 开启优化器跟踪
set session optimizer_trace='enabled=on';
select * from user where phone like '%156%';
-- 查看优化器追踪
select * from information_schema.optimizer_trace;

Here we look at TRACE on the line:

{
  "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, only the primary key query
set session optimizer_trace='enabled=on';
select id from user where phone like '%156%';
-- 查看优化器追踪
select * from information_schema.optimizer_trace;

Here we continue to look TRACE on the line:

{
  "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": [
        ]
      }
    }
  ]
}

Well, here we can find, analyze inside the Trace, did not show the actual choice of what the optimizer index for both SQL, but it just shows you are using a sequential scanning method to find the data.

Probably the only difference is that: a full table scan using the primary key index, while the other is to use a full table scan ordinary index; but the two did not spend the tree to find, which is useless on the characteristics of the B + Tree to improve query performance.

Sixth, concluded

1, when the full SQL query only fuzzy query result set as a primary key, because the cover index, the index will spend corresponding query field.

2, even if the index were using, but failed to find a tree to spend characteristics, but the normal order of traversal.

3, while the normal full table scan is the primary key index of the order of traversal, so that, in fact, the performance of both is actually the same.

Guess you like

Origin www.cnblogs.com/Howinfun/p/12449975.html
Recommended