MySQL之索引優(yōu)化

一腹纳、單表,多表查詢優(yōu)化:

多表查詢索引優(yōu)化:

\color{red}{左鏈接 索引建在右表 右鏈接 索引建在左表}

JOIN 語句優(yōu)化:
\color{red}{盡可能的減少Join語句中驱犹,NestedLoop的循環(huán)總次數:“永遠用小結果集驅動大的結果集”}

\color{red}{優(yōu)先優(yōu)化NestedLoop的內層循環(huán)嘲恍。}

\color{red}{保證Join語句中被驅動表中的Join條件字段已經被索引。}

\color{red}{當無法保證被驅動表中的Join條件字段被索引雄驹,并且內存資源充足的情況下佃牛,不要太吝嗇JoinBuffer的設置。}

二医舆、會導致索引失效的情況

1)俘侠、首先我們先建一個表;

CREATE TABLE `sys_user` (
  `id` varchar(64) NOT NULL COMMENT '主鍵',
  `name` varchar(64) DEFAULT NULL COMMENT '名字',
  `age` int(64) DEFAULT NULL COMMENT '年齡',
  `pos` varchar(64) DEFAULT NULL COMMENT '職位',
  PRIMARY KEY (`id`),
  KEY `idx_sys_user_nameAgePos` (`name`,`age`,`pos`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用戶表';

 2)蔬将、常見的索引失效原因:

全值匹配:

違背最左前綴原則:

全值匹配意思就是聯(lián)立的復合索引的順序和個數要和檢索的條件順序和個數相同爷速。
      最佳左前綴法則是指,如果索引了多列娃胆,要遵守最左前綴法則遍希。指的是查詢從索引的最左前列開始并且不跳過索引中的列
      下面我們給這個表建立一個復合索引

ALTER TABLE sys_user ADD INDEX idx_sys_user_nameAgePos(name,age,pos);

以下是我們的檢索語句:

SELECT * FROM sys_user WHERE name='小明' AND age = 22 AND pos ='java';
image

我們通過在檢索語句前面加關鍵字 EXLAIN,可以知道是否使用的索引

EXPLAIN SELECT * FROM sys_user WHERE name='小明' AND age = 22 AND pos ='java';
EXPLAIN SELECT * FROM sys_user WHERE name='小明' AND age = 22 ;
EXPLAIN SELECT * FROM sys_user WHERE name='小明'  AND pos ='java';
image
image
image

通過展示的結果我們可以知道里烦,第一個復合索引的三個字段我們都用了凿蒜,第二個復合索引我們只用到兩個字段禁谦,第三個復合索引我們只用到一個字段。三個語句我們都用到索引废封,顯然第一種是最優(yōu)的州泊。

我們再看看哪種情況會失效:

EXPLAIN SELECT * FROM sys_user WHERE age = 22;
EXPLAIN SELECT * FROM sys_user WHERE pos ='java';
EXPLAIN SELECT * FROM sys_user WHERE age = 22 AND pos ='java';
image
image
image

以上三種情況都變成了全表掃描,原因是違反了最左左前綴原則漂洋,因為復合索引最左邊的是name遥皂,當檢索條件name沒在前面索引將失效,第一種情況滿足了全值匹配刽漂,第二種滿足了兩個字段name和age演训,第三種因為只滿足了name,所以索引只用到name贝咙。

3)样悟、索引列上做計算、函數(自動或手動)類型轉換庭猩,會使索引失效轉為全表掃描

EXPLAIN SELECT * FROM sys_user WHERE  LEFT(name,1)='小明';
image

第七種情況失效是因為索引列做了計算或者函數的操作窟她,導致了全表掃描。

4)蔼水、存儲引擎不能使用索引中范圍條件右邊的列

可能大家關看上面的文字不知道是什么意思震糖,下面我們執(zhí)行一下查詢語句就清楚了

EXPLAIN SELECT * FROM sys_user WHERE name='小明' AND age < 22 AND pos ='java';
image

從上圖我們可以知道type變成了范圍級別,也就是說age<22之后的pos字段的索引失效了趴腋。

**5)吊说、盡量使用覆蓋索引(只訪問索引的查詢(索引列和查詢列一致),減少select * 的使用 **

這個就是字面意思于样,查詢具體的字段比查詢*效率更高疏叨,下面我們坐一下對比

EXPLAIN SELECT * FROM sys_user WHERE name='小明' AND age =22 AND pos ='java';
EXPLAIN SELECT name,age,pos FROM sys_user WHERE name='小明' AND age =22 AND pos ='java';
image
image

6)潘靖、mysql在使用不等于(!= 或者<>)的時候無法使用索引會導致全表掃描

EXPLAIN SELECT * FROM sys_user WHERE name !='小明'
image

結果顯示索引失效導致了全表掃描

7)穿剖、is null,is not null 也無法使用索引

EXPLAIN SELECT * FROM sys_user WHERE name is not null
image

8)卦溢、like以通配符開頭(’%abc…’)mysql索引會失效變成全表掃描的操作糊余,(%寫右邊則可以避免索引失效,如果業(yè)務實在需要’%abc…%'則可以用覆蓋索引避免索引失效)

EXPLAIN SELECT * FROM sys_user WHERE name like '%明%'
EXPLAIN SELECT * FROM sys_user WHERE name like '明%'
EXPLAIN SELECT name,age,pos FROM sys_user WHERE name like '%明%'
image
image
image

從上面的結果单寂,第一種索引失效,第二種只寫右邊的%則可以避免索引失效宣决,第三種如果業(yè)務實在需要‘%abc…%’這種sql蘸劈,則可以用覆蓋索引解決索引失效的問題

9)、字符串不加單引號索引會失效

EXPLAIN SELECT * FROM sys_user WHERE name=222;
image

因為檢索字符串是必須加單引號贤惯,上面用用了222是int類型孵构,mysql在檢索的時候會判斷name是varchar的類型會將222轉換為’222’進行檢索雾袱,索引列發(fā)生了類型轉換叹俏,故索引失效蝌数。

10)、少用or,用它連接時會索引失效

EXPLAIN SELECT * FROM sys_user WHERE name='小明' or age = 22;
image

結論:

定值(常量const)垢乙、范圍(range之后是失效)、還是排序(最終看排序)骂倘,一般order by是給個范圍。

group by 基本上都需要進行排序荧库,會有臨時表產生。

一般性建議:

對于單鍵索引,盡量選擇針對當前Query過濾性更好的索引

在選擇組合索引的時候屎勘,當前Query中過濾性最好的字段在索引字段順序中,位置越靠前越好

在選擇組合索引的時候,盡量選擇可以包含當前Query中的where字句中更多字段的索引

盡可能通過分析統(tǒng)計信息和調整Query的寫法來達到選擇合適索引的目的

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末这揣,一起剝皮案震驚了整個濱河市给赞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌残邀,老刑警劉巖罐旗,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門畅厢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人油狂,你說我怎么就攤上這事。” “怎么了仁堪?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵莺葫,是天一觀的道長。 經常有香客問我烤镐,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任缰贝,我火速辦了婚禮戏蔑,結果婚禮上,老公的妹妹穿的比我還像新娘捍壤。我一直安慰自己骤视,他們只是感情好,可當我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布鹃觉。 她就那樣靜靜地躺著专酗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪帜慢。 梳的紋絲不亂的頭發(fā)上笼裳,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天唯卖,我揣著相機與錄音粱玲,去河邊找鬼躬柬。 笑死,一個胖子當著我的面吹牛抽减,可吹牛的內容都是我干的允青。 我是一名探鬼主播,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼卵沉,長吁一口氣:“原來是場噩夢啊……” “哼颠锉!你這毒婦竟也來了?” 一聲冷哼從身側響起史汗,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤琼掠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后停撞,有當地人在樹林里發(fā)現(xiàn)了一具尸體瓷蛙,經...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年戈毒,在試婚紗的時候發(fā)現(xiàn)自己被綠了艰猬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡埋市,死狀恐怖冠桃,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情道宅,我是刑警寧澤食听,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站污茵,受9級特大地震影響樱报,放射性物質發(fā)生泄漏。R本人自食惡果不足惜省咨,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一肃弟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧零蓉,春花似錦笤受、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至章喉,卻和暖如春汗贫,著一層夾襖步出監(jiān)牢的瞬間身坐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工落包, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留部蛇,地道東北人。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓咐蝇,卻偏偏與公主長得像涯鲁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子有序,可洞房花燭夜當晚...
    茶點故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內容