MySQL數(shù)據(jù)庫(kù)-第六章:MySQL索引及執(zhí)行計(jì)劃

第二部分 MySQL 核心技術(shù)課程介紹

  1. 索引
  2. 存儲(chǔ)引擎
  3. 日志
  4. 備份
  5. 主從

===========================

1. 索引及執(zhí)行計(jì)劃

1.1 介紹

相當(dāng)于一本書(shū)中的目錄,優(yōu)化查詢.

1.2 MySQL索引的類型(算法)

BTREE (Banlance Tree) ******
HASH
FULLTEXT
RTREE
GIS

1.3 索引算法的演變

1.3.1 BTREE算法 由來(lái)

BTREE講究的是查找數(shù)據(jù)的平衡,讓我們的查詢可以快速鎖定范圍

1.3.2 BTREE 的增強(qiáng)之路

B-TREE ------> 葉子節(jié)點(diǎn)雙向指針 ------> 非葉子結(jié)點(diǎn)雙向指針 -----> B*TREE

1.3.3 BTREE 數(shù)據(jù)結(jié)構(gòu)構(gòu)建過(guò)程 *****

(1) 數(shù)據(jù)排序(默認(rèn)是從小到大)
(2) 將數(shù)據(jù)有序的存儲(chǔ)到16KB數(shù)據(jù)頁(yè),生成葉子(leaf node)節(jié)點(diǎn).
(3) 通過(guò)葉子節(jié)點(diǎn)范圍(最小值到下個(gè)葉子節(jié)點(diǎn)最小值)+每個(gè)葉子節(jié)點(diǎn)指針生成non-leaf.
(4) 通過(guò)non-leaf節(jié)點(diǎn)的范圍(最小值到下個(gè)non-leaf節(jié)點(diǎn)最小值)+每個(gè) non-leaf指針生成root.
(5) B*TREE中,為了進(jìn)一步優(yōu)化范圍查詢,加入了leaf雙向指針,non-leaf雙向指針.
1. 減少索引IO次數(shù),有效的較少IOPS
2. 減少了隨機(jī)IO的數(shù)量
3. 減少IO量級(jí)

1.4 MySQL的 索引組織表(InnoDB) ******

(1) Clusterd Index: 聚簇(聚集,集群)索引

前提:
1. MySQL默認(rèn)選擇主鍵(PK)列構(gòu)建聚簇索引BTREE.
2. 如果沒(méi)有主鍵,自動(dòng)選擇第一個(gè)唯一鍵的列構(gòu)建聚簇索引BTREE.
3. 如果以上都沒(méi)有,會(huì)自動(dòng)按照rowid生成聚簇索引.
說(shuō)明:
1. 聚簇索引,葉子節(jié)點(diǎn),就是原始的數(shù)據(jù)頁(yè),保存的是表整行數(shù)據(jù).
2. 為了保證我們的索引是"矮胖"結(jié)構(gòu),枝節(jié)點(diǎn)和根節(jié)點(diǎn)都是只保存ID列值范圍+下層指針.

(2) Secondary Index: 輔助(二級(jí))索引
構(gòu)建過(guò)程: alter table t1 add index idx(name)
1.提取name+id列的所有值
2.按照name自動(dòng)排序,有序的存儲(chǔ)到連續(xù)的數(shù)據(jù)頁(yè)中,生成葉子節(jié)點(diǎn)
3. 只提取葉子節(jié)點(diǎn)name范圍+指針,生成枝節(jié)點(diǎn)和根節(jié)點(diǎn)

(3) 針對(duì) name列的查詢,是如何優(yōu)化?
select * from t1 where name='bgx';
1. 按照查詢條件bgx,來(lái)帶基于Name列構(gòu)建的輔助索引進(jìn)行遍歷
理論上讀取page為3次,找到主鍵值
2. 根據(jù)ID值,回到聚簇索引樹(shù),繼續(xù)遍歷,進(jìn)而找到所需數(shù)據(jù)行.
理論讀取的數(shù)據(jù)頁(yè)為3次.

1.5 輔助索引細(xì)分

1.5.1 單列
1.5.2 聯(lián)合索引 *****

例如:
idx(a,b,c)
理論上可以有效的避免回表的次數(shù).

1.5.3 唯一索引

手機(jī)號(hào),身份證號(hào)類似的列.
理論上通過(guò)唯一索引作為遍歷條件的話,讀取6個(gè)page即可獲取數(shù)據(jù)行.

1.6 索引樹(shù)高度問(wèn)題,影響的原因?

(1) 數(shù)據(jù)行數(shù)多.
分區(qū)表(現(xiàn)在用的少).
歸檔表.
分庫(kù)分表
(2) 選取的索引列值過(guò)長(zhǎng)
前綴索引.
test(10)
(3) varchar(64) char(64) enum()等數(shù)據(jù)類型的影響

1.7 索引管理操作

1.7.1 查詢索引

desc city;
key:
PRI : 主鍵
UNI : 唯一鍵
MUL : 普通

mysql> show index from city\G
select 
table_schema,table_name,
column_name ,
data_type,Column_key ,
COLUMN_COMMENT from information_schema.columns 
WHERE table_schema NOT IN ('sys','informatiion_schema','performance_schema','mysql');
1.7.2 創(chuàng)建索引
例子:
-- 1. 單列索引例子
select * from city where population>10000000
索引設(shè)計(jì):
mysql> alter table city add index idx_popu(population);
說(shuō)明:
1. 作為 where 查詢條件的列.
2. 經(jīng)常作為 group by ,order by,distint,union的列創(chuàng)建索引.
-- 2. 聯(lián)合索引例子
select * from city where district='shandong' and name='jinan';
索引設(shè)計(jì):
mysql> alter table city add index idx_dis_name(district,name);

說(shuō)明:
聯(lián)合索引排列順序,從左到右.重復(fù)值少的列,優(yōu)先放在最左邊.

-- 3. 前綴索引應(yīng)用(字符串)
mysql> alter table city add index idx_name(name(5));
-- 4. 唯一索引
mysql> alter table student add unique index idx_tel(xtel);
mysql> desc student;

1.7.3 刪除索引

mysql> alter table city drop index idx_dis_name;

2. 執(zhí)行計(jì)劃(explain)分析

2.0 命令

    explain  select
    desc     select

2.1 使用場(chǎng)景

(1) 語(yǔ)句執(zhí)行之前 : 防患未然
(2) 出現(xiàn)慢語(yǔ)句時(shí) : 亡羊補(bǔ)牢

2.2 執(zhí)行計(jì)劃結(jié)果查看(優(yōu)化器選擇后的執(zhí)行計(jì)劃)

mysql> desc select * from city where countrycode='CHN';
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key         | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | city  | NULL       | ref  | CountryCode   | CountryCode | 3       | const |  363 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> 

2.3 重點(diǎn)關(guān)注指標(biāo)說(shuō)明

table: 發(fā)生在哪張表的執(zhí)行計(jì)劃.
type : 查詢的類型
全表掃描 : ALL
索引掃描 : index < range < ref < eq_ref < connst(system)< NULL *****
possible_keys : 可能用到的索引
key : 此次查詢走的索引名.
key_len : 索引覆蓋長(zhǎng)度.評(píng)估聯(lián)合索引應(yīng)用長(zhǎng)度的. *****
rows : 掃描了表中的多少行
Extra : 額外的信息 ****

2.4 type

(1) ALL : 全表掃描

mysql> desc select * from city;
mysql> desc select * from city where 1=1 ;
mysql> desc select * from city where population=42;
mysql> desc select * from city where countrycode !='CHN';
mysql> desc select * from city where countrycode not in ('CHN','USA');
mysql> desc select * from city where countrycode like '%CH%';

(2) index : 全索引掃描

mysql> desc select countrycode from city;

(3) range : 索引范圍掃描(最常見(jiàn))

>   <   >=  <=  like  
in or
mysql> desc select  *  from city where id<10;
mysql> desc select * from city where countrycode like 'CH%';
mysql> desc select * from city where countrycode  in ('CHN','USA');

改寫(xiě):

desc 
select * from city where countrycode='CHN'
union all 
select * from city where countrycode='USA'

(4) ref 輔助索引等值查詢

desc 
select * from city where countrycode='CHN';

(5) eq_ref 多表關(guān)聯(lián)查詢中,非驅(qū)動(dòng)表的連接條件是主鍵或唯一鍵

desc 
select 
city.name,
country.name ,
city.population 
from city 
join country 
on city.countrycode=country.code
where city.population<100;

(6) connst(system) :主鍵或者唯一鍵等值查詢

mysql> desc select * from city where id=10;

(7) NULL 索引中獲取不到數(shù)據(jù)

mysql> desc select * from city where id=100000;

2.5 key_len詳細(xì)說(shuō)明

2.5.1 作用

判斷聯(lián)合索引覆蓋長(zhǎng)度

2.5.2 最大覆蓋長(zhǎng)度的計(jì)算方法
idx(a,b,c)    ====> a(10)+b(20)+c(30)

(1) 影響計(jì)算的條件

字符集 : utf8mb4
數(shù)字類型
tinyint    1 Bytes
int        4 Bytes 
bigint     8 Bytes 
字符串類型
char(5)    5*4 Bytes
varchar(5) 5*4 Bytes + 2 Bytes
沒(méi)有 not null : 多一個(gè)字節(jié)存儲(chǔ)是否為空

測(cè)試表:

create table keyt (
id int not null primary key auto_increment,
num int not null, 
num1 int ,
k1 char(10) not null ,
k2 char(10) , 
k3 varchar(10) not null ,
k4 varchar(10)
)charset=utf8mb4;

num :  4 
num1:  5
k1  :  40 
k2  :  41
k3  :  42 
k4  :  43
2.5.3 聯(lián)合索引應(yīng)用"道道" *****

-- 建立聯(lián)合索引時(shí),最左側(cè)列,選擇重復(fù)值最少的列.
alter table keyt add index idx(a,b,c);

-- 例子:

-- 哪些情況可以完美應(yīng)用以上索引.
desc select *from student where xname='張三' and xage=11 and xgender='m';
desc select *from student where xage=11 and xgender='m' and xname='張三' ;
desc select *from student where xgender='m' and xname='張三' and xage=11 ;
-- 影響到聯(lián)合索引應(yīng)用長(zhǎng)度的.
-- 缺失 聯(lián)合索引最左列,不走任何索引
mysql> desc select *from student where xage=11 and xgender='m'  ;
-- 缺失中間部分,只能走丟失部分之前的索引部分
mysql> desc select *from student where xname ='張三'  and xgender='m'  ;

-- 查詢條件中,出現(xiàn)不等值查詢(> ,< ...like )

mysql> desc select *from student where xname ='張三' xage<18 and xgender='m'  ;

聯(lián)合索引應(yīng)用長(zhǎng)度到不等值列截?cái)嗔?
-- 多子句
按照 select 子句順序創(chuàng)建聯(lián)合索引.

案例: 碎片過(guò)多 alter table engine=InnoDB 重建表

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容