1.索引失效的原因
聯(lián)合索引排序的原理:先對(duì)第一個(gè)字段進(jìn)行排序,在第一個(gè)字段相同的情況下考慮第二個(gè)字段,然后在第二個(gè)字段相同的情況下才考慮第三個(gè)字段...

CREATE TABLE 'test_user'(
'id' int(11) not null auto_increment comment '主鍵id',
‘user_id’ varchar(36) not null comment '用戶id',
'phone' varchar(20) not null comment '用戶名稱',
'lan_id' int(9) not null comment '本地網(wǎng)',
'region_id' int(9) not null comment '區(qū)域'
)ENGINE=InnoDB Auto_increment=4057960 Default charset=utf8mb4;
假設(shè)將('phone', 'lan_id', 'region_id')組成的聯(lián)合索引
Explain select * from test_user where lan_id = 1;
此時(shí)的索引是失效的,因?yàn)槁?lián)合索引是遵循最左前綴法則即第一個(gè)字段有序的情況下lan_id才有序?,F(xiàn)在是跳過phone,直接搜索lan_id相當(dāng)于在一個(gè)無序的B+樹上搜索,所以只能全表掃描。
例1下例范圍查找的右邊索引會(huì)失效
Explain select * from test_user where a > 1 and b = 1;
為什么索引會(huì)失效?
因?yàn)槲覀兛梢哉业絘 >1的所有的節(jié)點(diǎn),但是此時(shí)的b索引是無序的,仍然不可以通過二分查找法來查找

例2. like查詢中,如果%放在兩邊或者放到左邊,它都是不走索引的。只有%放到右邊,它某些情況才會(huì)走這個(gè)索引。這是什么原因?
字符串在B+樹里面存儲(chǔ)的時(shí)候,它也是按照字母的大小去排序。首先按照第一個(gè)字母去比較,如果第一個(gè)字母相同則按照第二個(gè)字母去比較和最佳左前綴法則相似。如果左邊用了%,那后面的字符是無序的,此時(shí)就不能使用二分查找來定位元素還是退化為了全表掃描。
3.Mysql中的索引查詢?yōu)槭裁词褂昧薆+樹結(jié)構(gòu),而不使用哈希索引或者B樹?
首先哈希值是無序的,不能夠進(jìn)行范圍查找。
平衡二叉樹的缺點(diǎn)是當(dāng)數(shù)據(jù)量非常大的時(shí)候,其深度也會(huì)非常深這樣也會(huì)導(dǎo)致查找效率慢。其次其存在回旋查找的問題。比如說當(dāng)存在范圍查詢>5的時(shí)候定位到該元素之后還得回溯到前面的節(jié)點(diǎn)元素6,7
B樹的最大特點(diǎn)是一個(gè)節(jié)點(diǎn)可以存儲(chǔ)多個(gè)值,這樣可以使得樹的高度變矮,從而使得樹的查找速度變快。但是其也存在回旋查找的問題。

B+樹則解決了這個(gè)問題,它的非葉子節(jié)點(diǎn)存儲(chǔ)的是key,其葉子節(jié)點(diǎn)既存儲(chǔ)了key也存儲(chǔ)了value并且其葉子節(jié)點(diǎn)是有序的,節(jié)點(diǎn)之間用指針相連也正是因?yàn)檫@一點(diǎn)使得B+樹在范圍查詢的時(shí)候不存在回旋問題。