mysql索引的使用和優(yōu)化

索引是一種特殊的文件(InnoDB 數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分)驯遇,它們包含著對(duì)數(shù)據(jù)表里的所有記錄的引用指針惨寿。更通俗的說硕勿,數(shù)據(jù)庫索引就好比一本書的目錄,能夠加快數(shù)據(jù)庫的查詢速度钓试。
首先感謝網(wǎng)上的那些前輩和大神們的無私分享
最近在學(xué)習(xí)mysql的優(yōu)化問題,在查詢中正確使用索引,對(duì)查詢效率的提升有非常大的幫助,使用不當(dāng)會(huì)使索引失效,起不到索引該有的作用。把這兩天學(xué)到的知識(shí)記錄一下副瀑。

使用索引的優(yōu)勢(shì)

  1. 提高數(shù)據(jù)的檢索速度弓熏,降低數(shù)據(jù)庫IO成本:使用索引的意義就是通過縮小表中需要查詢的記錄的數(shù)目從而加快搜索的速度。
  2. 降低數(shù)據(jù)排序的成本糠睡,降低CPU消耗:索引之所以查的快挽鞠,是因?yàn)橄葘?shù)據(jù)排好序,若該字段正好需要排序狈孔,則真好降低了排序的成本信认。

使用索引帶來的問題

1.占用存儲(chǔ)空間:索引實(shí)際上也是一張表,記錄了主鍵與索引字段均抽,一般以索引文件的形式存儲(chǔ)在磁盤上嫁赏。

  1. 降低更新表的速度:表的數(shù)據(jù)發(fā)生了變化,對(duì)應(yīng)的索引也需要一起變更油挥,從而減低的更新速度潦蝇。否則索引指向的物理數(shù)據(jù)可能不對(duì),這也是索引失效的原因之一深寥。

索引的類型

1.normal:
表示普通索引,它沒有任何限制攘乒,MyISAM 中默認(rèn)的 B-tree 類型的索引
2.unique:
表示唯一的,不允許重復(fù)的索引惋鹅,但是允許有空值则酝。如果該字段信息保證不會(huì)重復(fù)例如身份證號(hào)用作索引時(shí),可設(shè)置為unique负饲。
3.full textl:
表示全文搜索的索引堤魁。 FULLTEXT 用于搜索很長(zhǎng)一篇文章的時(shí)候喂链,效果最好。注意僅 MyISAM 引擎支持
4.組合索引(最左前綴)
平時(shí)用的SQL查詢語句一般都有比較多的限制條件妥泉,所以為了進(jìn)一步榨取MySQL的效率椭微,就要考慮建立組合索引。使用組合索引時(shí)注意最左匹配原則盲链。
比如新建索引ALTER TABLE testADD INDEX 'id_name_age' ('id','name','age')蝇率。
在查詢的時(shí)SELECT * FROM user WHERE id =1 AND name='bruce'索引起作用。
但是查詢時(shí)SELECT * FROM user WHERE name='bruce' AND age = 18這時(shí)候索引不起作用刽沾。
至于原因,因?yàn)檩o助索引是B+樹實(shí)現(xiàn)的本慕,雖然可以指定多個(gè)列,但是每個(gè)列的比較優(yōu)先級(jí)不一樣侧漓,寫在前面的優(yōu)先比較锅尘。一旦出現(xiàn)遺漏,在B+樹上就無法繼續(xù)搜索了(通過補(bǔ)齊等措施解決的除外)布蔗,因此是按照最左連續(xù)匹配來的藤违。既然是在B+樹上搜索,對(duì)于條件的比較自然是要求精確匹配(即"="和"IN")纵揍。不過順序倒是可以顛倒顿乒,因?yàn)椴樵儍?yōu)化器重排序一下就好了。

索引的優(yōu)化

  • 應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行 null 值判斷泽谨,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描璧榄,如:
    select id from t where num is null,可以在num上設(shè)置默認(rèn)值0,確保表中num列沒有null值吧雹,然后這樣查詢:
    select id from t where num=0
  • 應(yīng)盡量避免在 where 子句中使用!=或<>操作符骨杂,否則將引擎放棄使用索引而進(jìn)行全表掃描。優(yōu)化器將無法通過索引來確定將要命中的行數(shù),因此需要搜索該表的所有行吮炕。
  • 應(yīng)盡量避免在 where 子句中使用 or 來連接條件腊脱,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如:
    select id from t where num=10 or num=20
  • 盡量避免在索引過的字符數(shù)據(jù)中龙亲,使用非打頭字母搜索陕凹。這也使得引擎無法利用索引。
    見如下例子:
    SELECT * FROM T1 WHERE NAME LIKE ‘%L%’
    SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’
    SELECT * FROM T1 WHERE NAME LIKE ‘L%’
  • 應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行表達(dá)式操作鳄炉,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描
  • 應(yīng)盡量避免在where子句中對(duì)字段進(jìn)行函數(shù)操作杜耙,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描
  • 不要在 where 子句中的“=”左邊進(jìn)行函數(shù)、算術(shù)運(yùn)算或其他表達(dá)式運(yùn)算拂盯,否則系統(tǒng)將可能無法正確使用索引

總結(jié)

哪些情況需要建索引:

1 主鍵佑女,唯一索引
2 經(jīng)常用作查詢條件的字段需要?jiǎng)?chuàng)建索引
3 經(jīng)常需要排序、分組和統(tǒng)計(jì)的字段需要建立索引
4 查詢中與其他表關(guān)聯(lián)的字段,外鍵關(guān)系建立索引

哪些情況不要建索引:

1 表的記錄太少团驱,百萬級(jí)以下的數(shù)據(jù)不需要?jiǎng)?chuàng)建索引,數(shù)據(jù)量很少的時(shí)候,索引帶來的提升不夠明顯
2 經(jīng)常增刪改的表不需要?jiǎng)?chuàng)建索引(在修改表的內(nèi)容時(shí)摸吠,索引必須進(jìn)行更新,有時(shí)可能需要重構(gòu)嚎花,因此寸痢,索引越多,所花的時(shí)間越長(zhǎng)紊选。)
3 數(shù)據(jù)重復(fù)且分布平均的字段不需要?jiǎng)?chuàng)建索引啼止,如 true,false 之類。(體現(xiàn)不出索引帶來的價(jià)值)
4 頻發(fā)更新的字段不適合創(chuàng)建索引(和2同理)
5 where條件里用不到的字段不需要?jiǎng)?chuàng)建索引(索引起不到作用)

使用注意:

  • 性能優(yōu)化過程中兵罢,選擇在哪個(gè)列上創(chuàng)建索引是最重要的步驟之一献烦。可以考慮使用索引的主要有兩種類型的列:在where子句中出現(xiàn)的列卖词,在join子句中出現(xiàn)的列巩那。
  • 考慮列中值的分布,索引的列的基數(shù)越大此蜈,索引的效果越好拢操。
  • 使用短索引,如果對(duì)字符串列進(jìn)行索引舶替,應(yīng)該指定一個(gè)前綴長(zhǎng)度,可節(jié)省大量索引空間杠园,提升查詢速度顾瞪。
  • 不要過度索引,只保持所需的索引抛蚁。每個(gè)額外的索引都要占用額外的磁盤空間陈醒,并降低寫操作的性能。
  • 在修改表的內(nèi)容時(shí)瞧甩,索引必須進(jìn)行更新钉跷,有時(shí)可能需要重構(gòu),因此肚逸,索引越多爷辙,所花的時(shí)間越長(zhǎng)。
  • MySQL只對(duì)一下操作符才使用索引:<,<=,=,>,>=,between,in, 以及某些時(shí)候的like(不以通配符%或_開頭的情形)朦促。

再次感謝前輩們的無私分享

我也是在學(xué)習(xí)中,文中如有錯(cuò)誤的地方,歡迎在評(píng)論區(qū)指出,方便共同學(xué)習(xí)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末膝晾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子务冕,更是在濱河造成了極大的恐慌血当,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,222評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異臊旭,居然都是意外死亡落恼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門离熏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來佳谦,“玉大人,你說我怎么就攤上這事撤奸》驼眩” “怎么了?”我有些...
    開封第一講書人閱讀 157,720評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵胧瓜,是天一觀的道長(zhǎng)矢棚。 經(jīng)常有香客問我,道長(zhǎng)府喳,這世上最難降的妖魔是什么蒲肋? 我笑而不...
    開封第一講書人閱讀 56,568評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮钝满,結(jié)果婚禮上兜粘,老公的妹妹穿的比我還像新娘。我一直安慰自己弯蚜,他們只是感情好孔轴,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,696評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著碎捺,像睡著了一般路鹰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上收厨,一...
    開封第一講書人閱讀 49,879評(píng)論 1 290
  • 那天晋柱,我揣著相機(jī)與錄音,去河邊找鬼诵叁。 笑死雁竞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拧额。 我是一名探鬼主播碑诉,決...
    沈念sama閱讀 39,028評(píng)論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼势腮!你這毒婦竟也來了联贩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,773評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤捎拯,失蹤者是張志新(化名)和其女友劉穎泪幌,沒想到半個(gè)月后盲厌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,220評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祸泪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,550評(píng)論 2 327
  • 正文 我和宋清朗相戀三年吗浩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片没隘。...
    茶點(diǎn)故事閱讀 38,697評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡懂扼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出右蒲,到底是詐尸還是另有隱情阀湿,我是刑警寧澤,帶...
    沈念sama閱讀 34,360評(píng)論 4 332
  • 正文 年R本政府宣布瑰妄,位于F島的核電站陷嘴,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏间坐。R本人自食惡果不足惜灾挨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,002評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望竹宋。 院中可真熱鬧劳澄,春花似錦、人聲如沸蜈七。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽飒硅。三九已至溯警,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間狡相,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工食磕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尽棕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,433評(píng)論 2 360
  • 正文 我出身青樓彬伦,卻偏偏與公主長(zhǎng)得像滔悉,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子单绑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,587評(píng)論 2 350