MySQL (Advanced, Interview) - (MySQL Optimization 2) Explain Optimizing MySQL Indexes

       1. Introduction

        Indexes are established for more efficient data querying. How to use database indexes correctly and how to prevent indexes from becoming invalid. The following points are the basic principles we follow.

Let’s first review the execution order of MySQL statements.

SQL Execution Sequence
     If you want to optimize SQL, you must clearly know the execution sequence of SQL. In this way, you can get twice the result with half the effort by working with explain!

Complete SQL statement

select distinct 
        <select_list>
from
    <left_table><join_type>
join <right_table> on <join_condition>
where
    <where_condition>
group by
    <group_by_list>
having
    <having_condition>
order by
    <order_by_condition>
limit <limit number>
3.2 SQL执行顺序

Execution order

1、from <left_table><join_type>
2、on <join_condition>
3、<join_type> join <right_table>
4、where <where_condition>
5、group by <group_by_list>
6、having <having_condition>
7、select
8、distinct <select_list>
9、order by <order_by_condition>
10、limit <limit_number>

 It can be seen from the execution sequence of SQL that the first choice is to filter conditions through the subject to reduce the amount of query data as much as possible, and then perform query statistics through select. In other words, the things we can optimize are concentrated before Article 7.
 

2. Case Demonstration Index Optimization

Preparation

2.1 Create table

REATE TABLE `staffs` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `name` varchar(24) NOT NULL DEFAULT '' COMMENT '姓名',
  `age` int(11) NOT NULL DEFAULT '0' COMMENT '年龄',
  `pos` varchar(20) NOT NULL COMMENT '职位',
  `add_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入职时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.2 Insert basic data

INSERT INTO `test`.`staffs` (`id`, `name`, `age`, `pos`, `add_time`) VALUES ('1', '王二', '25', '总经理', '2018-05-22 09:45:44');
INSERT INTO `test`.`staffs` (`id`, `name`, `age`, `pos`, `add_time`) VALUES ('2', 'July', '25', '实习生', '2018-05-22 09:45:58');
INSERT INTO `test`.`staffs` (`id`, `name`, `age`, `pos`, `add_time`) VALUES ('3', '李四', '20', '实习生', '2018-05-22 09:46:04');
INSERT INTO `test`.`staffs` (`id`, `name`, `age`, `pos`, `add_time`) VALUES ('4', '王玉', '21', '老板娘', '2018-05-22 09:46:17');
INSERT INTO `test`.`staffs` (`id`, `name`, `age`, `pos`, `add_time`) VALUES ('5', '王五', '22', '服务员', '2018-05-22 09:46:26');
INSERT INTO `test`.`staffs` (`id`, `name`, `age`, `pos`, `add_time`) VALUES ('6', '赵六', '80', '传菜生', '2018-05-22 09:46:45');

2.3 Create index

ALTER TABLE staffs ADD INDEX idx_staffs_nameAgePos (NAME, age, pos);

2.4 Query index

SHOW INDEX FROM staffs

Write picture description here

Practical analysis , combined with the previous article to look at  MySQL - (MySQL Optimization 1) Explain detailed explanation


MYSQL EXPLAIN parses USING INDEX, USING WHERE, USING INDEX CONDITION using index and using where as long as the index is used in EXTRA. We can often see it, and using index condition is a new feature added after mysql5.6.

using index : It will appear when using a covering index.
using where : When searching using an index, you need to go back to the table to query the required data.
using index condition : The search uses the index, but you need to go back to the table to query the data
. using index & using where : The search uses an index, but the required data can be found in the index columns, so there is no need to go back to the table to query the data.

3. Index failure optimization case

3.1  Full Value Match My Favorite

 Full value matching means that the fields and order of the statement I want to query are exactly the same as the fields and order of the established index, otherwise the index will fail.

Correct way to use

EXPLAIN SELECT * FROM staffs WHERE NAME = 'July';

Write picture description here

 EXPLAIN SELECT * FROM staffs WHERE NAME = 'July' AND age = 25;

Write picture description here

EXPLAIN SELECT * FROM staffs WHERE NAME = 'July' AND age = 25 AND pos = '实习生'

Write picture description here

 Index failure

EXPLAIN SELECT * FROM staffs WHERE age = 25 AND pos = '实习生';

Write picture description here

EXPLAIN SELECT * FROM staffs WHERE pos = '实习生';

Write picture description here

 Summary: From the above results, we can see that when the index is established in the order of name, age, and pos, if the query condition does not start with name, the index will fail. To sum it up in one sentence:带头大哥不能死!

3.2 Best Left Prefix Rule

If multiple columns are indexed, the leftmost prefix rule must be followed , which means that the query starts from the leftmost front column of the index and 不跳过索引中的列.

EXPLAIN SELECT * FROM staffs WHERE NAME = 'July' AND pos = '实习生';

Write picture description here

As shown in the figure above, if two index fields are matched, then key_len should be at least greater than 74, and ref should be two const. It can be seen that the query statement only uses the index of the name field, and the subsequent indexes are invalid.

✈ Summary : From the above results, we can see that when the index is established in the order of name, age, and pos, if the query condition starts with name but is not in order, the subsequent indexes will be invalid. To sum up, one sentence is: the middle brothers cannot be separated!

 2.3 Do not perform any operations on index columns

        Any operation here, including calculations, functions, (automatic or manual) type conversions, will cause the index to fail and turn to a full table scan.

EXPLAIN SELECT * FROM staffs WHERE NAME = 'July';

Write picture description here

EXPLAIN SELECT * FROM staffs WHERE left(NAME,4) = 'July';

Write picture description here

2.4 The storage engine cannot use the columns to the right of the range condition in the index

EXPLAIN SELECT * FROM staffs WHERE NAME = 'July' AND age = 25 AND pos = '实习生';

 Write picture description here

EXPLAIN SELECT * FROM staffs WHERE NAME = 'July' AND age > 25 AND pos = '实习生';

Write picture description here

  Summary: When we use range search such as age > 25, type changes to range, and key_len is equal to 78, indicating that name and age indexes have been used, but the age index changes to range sorting, not accurate Searching will cause the subsequent pos index to become invalid. So the summary is:范围之后全失效!

2.5 Try to use covering indexes

 Try to use indexed queries, that is, the index columns and query columns are consistent to reduce select *

EXPLAIN SELECT * FROM staffs WHERE NAME = 'July' AND age = 25 AND pos = '实习生';

Write picture description here

EXPLAIN SELECT name,age,pos FROM staffs WHERE NAME = 'July' AND age = 25 AND pos = '实习生';

Write picture description here

EXPLAIN SELECT name,age,pos FROM staffs WHERE NAME = 'July' AND age > 25 AND pos = '实习生';

Write picture description here

 2.6 Mysql cannot use indexes when using not equal to (!= or <>), resulting in full table scan

EXPLAIN SELECT * FROM staffs WHERE NAME = 'July';

Write picture description here

EXPLAIN SELECT * FROM staffs WHERE name != 'July';

Write picture description here

EXPLAIN SELECT * FROM staffs WHERE name <> 'July';

Write picture description here

 2.7 Index cannot be used even if is null or is not null

2.8 If like starts with a wildcard character ('%abc...'), if the index fails, it will become a full table scan.

2.9 String index without single quotes fails

2.10 Use or less, as the index will become invalid when used to connect.

EXPLAIN SELECT * FROM staffs WHERE name = 'July' or age = 25

Write picture description here

 3.3 General suggestions
For single-key indexes, try to choose an index with better filterability for the current query. When
selecting a combined index, the field with the best filterability in the current query should be in the order of the index fields. The earlier the position, the better.
When combining indexes, try to choose an index that can include more fields in the where clause in the current query. Try to
select the appropriate index by analyzing statistical information and adjusting the way the query is written.
3.4 Optimization Summary Tips
 

全值匹配我最爱,最左前缀要遵守;
带头大哥不能死,中间兄弟不能断;
索引列上少计算,范围之后全失效;
LIKE百分写最右,覆盖索引不写星;
不能空值还有OR,索引失效要少用;
VAR引号不可丢,SQL高级也不难;

Original link: [MySQL Advanced] (4) Index Optimization Index Failure_Wang Hongyu’s Blog-CSDN Blog_MySQL Range Query Index Failure

Guess you like

Origin blog.csdn.net/u010445301/article/details/126235856