MYSQL index optimization, to avoid the back to the table

" The rapid positioning inefficient SQL? "I left a tail:

select id,name where name='shenjian'

select id,name,sex where name='shenjian'

Multi-query a property, why retrieval process is completely different?

 

What is the query back to the table?

What is an index covering?

How to achieve index covering?

What scenario can be optimized using the SQL index coverage?

 

Of these, which it is today to share content.

Voiceover: This test is based on MySQL5.6-InnoDB.

 

First, what is the query back to the table?

 

It must first achieve the index from InnoDB talking about, InnoDB, there are two indexes:

  • Clustered index (clustered index)

  • General index (secondary index)

 

InnoDB clustered index and the general index What's the difference?

 

InnoDB clustered index leaf node storage rows, and therefore, there must be InnoDB, and only one clustered index:

(1) If the table is defined PK, PK is the clustered index;

(2) If the table is not defined PK, then the first column is not NULL unique clustered index;

(3) Otherwise, InnoDB will create a hidden row-id as a clustered index;

Voiceover: So PK queries very fast, positioned directly rows.

 

InnoDB general index leaf node stores the primary key value.

VO: Note that, instead of the recording head pointer memory row, the record pointer index leaf node stores the MyISAM.

 

For chestnut, with a wish list:

t(id PK, name KEY, sex, flag);

Voiceover: id is a clustered index, name is the general index.

 

Table has four records:

1, shenjian, m, A

3, zhangsan, m, A

5, lisi, I, A

9, wangwu, f, B

B + tree index two are shown above:

(1) id as PK, clustered index, the leaf node stores rows;

(2) name as the KEY, the general index, the leaf node stores PK values, i.e., ID;

 

Since the general index can not be positioned directly rows, and that the general index of the query process is kind of how it?

Typically, the code needs to be scanned twice index tree.

 

E.g:

select * from t where name='lisi';

It is how to implement it?

The pink path, the code needs to be scanned twice index tree:

(1) positioned by the first ordinary index to the primary key value id = 5;

(2) by positioning the clustered index rows;

 

This is called back to the table query , first locate the primary key value, and then locate the line record, its performance is lower than the sweep over the index tree.

 

Second, what is the index covering (Covering index) ?

The amount, the landlord did not find this concept in MySQL's official website.

Voiceover: rigorous scholarship, right?

 

SQL-Server borrow the official website of the argument.

 

MySQL's official website, a similar statement appears in the query plan optimization chapters explain that explain the output Extra field is Using index, the index can trigger coverage.

 

Whether it is the official website of SQL-Server, or MySQL official website, we have expressed: only need to be able to get all the required data columns in a SQL index tree without having to return to the table faster.

 

Third, how to achieve index covering?

Common methods are: the field is queried, the establishment of a joint index to go.

 

Still " rapid positioning inefficient SQL? "The example:

create table user (

id int primary key,

name varchar(20),

sex varchar(5),

index(name)

)engine=innodb;

 

The first SQL statement:

select id,name from user where name='shenjian';

能够命中name索引,索引叶子节点存储了主键id,通过name的索引树即可获取id和name,无需回表,符合索引覆盖,效率较高。

画外音,Extra:Using index

 

第二个SQL语句:                     

select id,name,sex from user where name='shenjian';

能够命中name索引,索引叶子节点存储了主键id,但sex字段必须回表查询才能获取到,不符合索引覆盖,需要再次通过id值扫码聚集索引获取sex字段,效率会降低。

画外音,Extra:Using index condition

 

如果把(name)单列索引升级为联合索引(name, sex)就不同了。

create table user (

id int primary key,

name varchar(20),

sex varchar(5),

index(name, sex)

)engine=innodb;

可以看到:

select id,name ... where name='shenjian';

select id,name,sex ... where name='shenjian';

都能够命中索引覆盖,无需回表。

画外音,Extra:Using index

 

 

四、哪些场景可以利用索引覆盖来优化SQL?

场景1:全表count查询优化

原表为:

user(PK id, name, sex);

 

直接:

select count(name) from user;

不能利用索引覆盖。

 

添加索引:

alter table user add key(name);

就能够利用索引覆盖提效。

 

场景2:列查询回表优化

select id,name,sex ... where name='shenjian';

这个例子不再赘述,将单列索引(name)升级为联合索引(name, sex),即可避免回表。

 

场景3:分页查询

select id,name,sex ... order by name limit 500,100;

将单列索引(name)升级为联合索引(name, sex),也可以避免回表。

 

InnoDB聚集索引普通索引回表索引覆盖,希望这1分钟大家有收获。

 

提示,如果你不清楚explain结果Extra字段为Using index的含义,请阅读前序文章:《如何利用工具,迅猛定位低效SQL?

 

 

出处:https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651962609&idx=1&sn=46e59691257188d33a91648640bcffa5&chksm=bd2d092d8a5a803baea59510259b28f0669dbb72b6a5e90a465205e9497e5173d13e3bb51b19&mpshare=1&scene=1&srcid=&sharer_sharetime=1564396837343&sharer_shareid=7cd5f6d8b77d171f90b241828891a85f&key=abd60b96b5d1f2e52ca45314fb2c95a67fad7a457fe265562eb51a1c026389d3f28c52359f96e920368ab44a5d08ebcbbe2ded474be2ba70731ed8b5dcc5dd68cc0eceb4989a74fb04e5055c78af8d38&ascene=1&uin=MTAwMjA4NTM0Mw%3D%3D&devicetype=Windows+7&version=62060739&lang=zh_CN&pass_ticket=tXA4xc7SZYamLpGZz5B6JwJa1ZRvZ4bRlmzFhXwEKeOfloPLulU0O80gsIQUiONb  

 

 

Guess you like

Origin www.cnblogs.com/webnginx/p/11908217.html