Mysql 索引及優(yōu)化

??索引對查詢的速度有著至關(guān)重要的影響朝抖,理解索引也是進行數(shù)據(jù)庫性能調(diào)優(yōu)的起點糊闽∈崦担考慮如下情況,假設(shè)數(shù)據(jù)庫中一個表有106條記錄右犹,DBMS的頁面大小為4K提澎,并存儲100條記錄。如果沒有索引傀履,查詢將對整個表進行掃描虱朵,最壞的情況下,如果所有數(shù)據(jù)頁都不在內(nèi)存钓账,需要讀取104個頁面碴犬,如果這104個頁面在磁盤上隨機分布,需要進行104次I/O梆暮,假設(shè)磁盤每次I/O時間為10ms(忽略數(shù)據(jù)傳輸時間)服协,則總共需要100s(但實際上要好很多很多)。如果對之建立B-Tree索引啦粹,則只需要進行l(wèi)og100(10^6)=3次頁面讀取偿荷,最壞情況下耗時30ms。這就是索引帶來的效果唠椭,很多時候跳纳,當(dāng)你的應(yīng)用程序進行SQL查詢速度很慢時,應(yīng)該想想是否可以建索引贪嫂。

索引與優(yōu)化

選擇索引的數(shù)據(jù)類型

MySQL支持很多數(shù)據(jù)類型寺庄,選擇合適的數(shù)據(jù)類型存儲數(shù)據(jù)對性能有很大的影響。通常來說,可以遵循以下一些指導(dǎo)原則:
(1)越小的數(shù)據(jù)類型通常更好:越小的數(shù)據(jù)類型通常在磁盤斗塘、內(nèi)存和CPU緩存中都需要更少的空間赢织,處理起來更快。
(2)簡單的數(shù)據(jù)類型更好:整型數(shù)據(jù)比起字符馍盟,處理開銷更小于置,因為字符串的比較更復(fù)雜。在MySQL中贞岭,應(yīng)該用內(nèi)置的日期和時間數(shù)據(jù)類型八毯,而不是用字符串來存儲時間;以及用整型數(shù)據(jù)類型存儲IP地址瞄桨。
(3)盡量避免NULL:應(yīng)該指定列為NOT NULL宪彩,除非你想存儲NULL。在MySQL中讲婚,含有空值的列很難進行查詢優(yōu)化,因為它們使得索引俊柔、索引的統(tǒng)計信息以及比較運算更加復(fù)雜筹麸。你應(yīng)該用0、一個特殊的值或者一個空串代替空值雏婶。

選擇標識符

選擇合適的標識符是非常重要的物赶。選擇時不僅應(yīng)該考慮存儲類型,而且應(yīng)該考慮MySQL是怎樣進行運算和比較的留晚。一旦選定數(shù)據(jù)類型酵紫,應(yīng)該保證所有相關(guān)的表都使用相同的數(shù)據(jù)類型。
(1) 整型:通常是作為標識符的最好選擇错维,因為可以更快的處理奖地,而且可以設(shè)置為AUTO_INCREMENT。
(2) 字符串:盡量避免使用字符串作為標識符赋焕,它們消耗更好的空間参歹,處理起來也較慢。而且隆判,通常來說犬庇,字符串都是隨機的,所以它們在索引中的位置也是隨機的侨嘀,這會導(dǎo)致頁面分裂臭挽、隨機訪問磁盤,聚簇索引分裂(對于使用聚簇索引的存儲引擎)咬腕。

索引入門

對于任何DBMS欢峰,索引都是進行優(yōu)化的最主要的因素。對于少量的數(shù)據(jù),沒有合適的索引影響不是很大赤赊,但是闯狱,當(dāng)隨著數(shù)據(jù)量的增加,性能會急劇下降抛计。
如果對多列進行索引(組合索引)哄孤,列的順序非常重要,MySQL僅能對索引最左邊的前綴進行有效的查找吹截。例如:
假設(shè)存在組合索引it1c1c2(c1,c2)瘦陈,查詢語句select * from t1 where c1=1 and c2=2能夠使用該索引。查詢語句select * from t1 where c1=1也能夠使用該索引波俄。但是晨逝,查詢語句select * from t1 where c2=2不能夠使用該索引,因為沒有組合索引的引導(dǎo)列懦铺,即捉貌,要想使用c2列進行查找,必需出現(xiàn)c1等于某值冬念。

索引的類型

B-Tree索引

CREATE TABLE People (
   last_name varchar(50)    not null,
   first_name varchar(50)    not null,
   dob        date           not null,
   gender     enum('m', 'f') not null,
   key(last_name, first_name, dob)
);

索引存儲的值按索引列中的順序排列趁窃。可以利用B-Tree索引進行全關(guān)鍵字急前、關(guān)鍵字范圍和關(guān)鍵字前綴查詢醒陆,當(dāng)然,如果想使用索引裆针,你必須保證按索引的最左邊前綴(leftmost prefix of the index)來進行查詢刨摩。
(1)匹配全值(Match the full value):對索引中的所有列都指定具體的值。例如世吨,上圖中索引可以幫助你查找出生于1960-01-01的Cuba Allen澡刹。
(2)匹配最左前綴(Match a leftmost prefix):你可以利用索引查找last name為Allen的人,僅僅使用索引中的第1列另假。
(3)匹配列前綴(Match a column prefix):例如像屋,你可以利用索引查找last name以J開始的人,這僅僅使用索引中的第1列边篮。
(4)匹配值的范圍查詢(Match a range of values):可以利用索引查找last name在Allen和Barrymore之間的人己莺,僅僅使用索引中第1列。
(5)匹配部分精確而其它部分進行范圍匹配(Match one part exactly and match a range on another part):可以利用索引查找last name為Allen戈轿,而first name以字母K開始的人凌受。
(6)僅對索引進行查詢(Index-only queries):如果查詢的列都位于索引中,則不需要讀取元組的值思杯。
由于B-樹中的節(jié)點都是順序存儲的胜蛉,所以可以利用索引進行查找(找某些值)挠进,也可以對查詢結(jié)果進行ORDER BY。當(dāng)然誊册,使用B-tree索引有以下一些限制:
(1) 查詢必須從索引的最左邊的列開始领突。關(guān)于這點已經(jīng)提了很多遍了。例如你不能利用索引查找在某一天出生的人案怯。
(2) 不能跳過某一索引列君旦。例如,你不能利用索引查找last name為Smith且出生于某一天的人嘲碱。
(3) 存儲引擎不能使用索引中范圍條件右邊的列金砍。例如,如果你的查詢語句為WHERE last_name="Smith" AND first_name LIKE 'J%' AND dob='1976-12-23'麦锯,則該查詢只會使用索引中的前兩列恕稠,因為LIKE是范圍查詢。

Hash索引

MySQL中扶欣,只有Memory存儲引擎顯示支持hash索引鹅巍,是Memory表的默認索引類型,盡管Memory表也可以使用B-Tree索引料祠。Memory存儲引擎支持非唯一hash索引昆著,這在數(shù)據(jù)庫領(lǐng)域是罕見的,如果多個值有相同的hash code术陶,索引把它們的行指針用鏈表保存到同一個hash表項中。
假設(shè)創(chuàng)建如下一個表:

CREATE TABLE testhash (
   fname VARCHAR(50) NOT NULL,
   lname VARCHAR(50) NOT NULL,
   KEY USING HASH(fname)
) ENGINE=MEMORY;

假設(shè)索引使用hash函數(shù)f( )煤痕,如下:

f('Arjen') = 2323
f('Baron') = 7437
f('Peter') = 8784
f('Vadim') = 2458

此時,索引結(jié)果如下

2323  -> row 1
2458  -> row 4
7437  -> row 2
8784  -> row 3

Slots是有序的梧宫,但是記錄不是有序的。當(dāng)你執(zhí)行
mysql> SELECT lname FROM testhash WHERE fname='Peter';
MySQL會計算’Peter’的hash值摆碉,然后通過它來查詢索引的行指針塘匣。因為f('Peter') = 8784,MySQL會在索引中查找8784巷帝,得到指向記錄3的指針忌卤。
因為索引自己僅僅存儲很短的值,所以楞泼,索引非常緊湊驰徊。Hash值不取決于列的數(shù)據(jù)類型,一個TINYINT列的索引與一個長字符串列的索引一樣大堕阔。

Hash索引有以下一些限制:
(1)由于索引僅包含hash code和記錄指針棍厂,所以,MySQL不能通過使用索引避免讀取記錄超陆。但是訪問內(nèi)存中的記錄是非常迅速的牺弹,不會對性造成太大的影響。
(2)不能使用hash索引排序。
(3)Hash索引不支持鍵的部分匹配张漂,因為是通過整個索引值來計算hash值的晶默。
(4)Hash索引只支持等值比較,例如使用=航攒,IN( )和<=>磺陡。對于WHERE price>100并不能加速查詢。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屎债,一起剝皮案震驚了整個濱河市仅政,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盆驹,老刑警劉巖圆丹,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異躯喇,居然都是意外死亡廉丽,警方通過查閱死者的電腦和手機正压,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拓劝,“玉大人郑临,你說我怎么就攤上這事〉浞睿” “怎么了获枝?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵嚣崭,是天一觀的道長。 經(jīng)常有香客問我说榆,道長签财,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮屁魏,結(jié)果婚禮上氓拼,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好唱歧,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布沿后。 她就那樣靜靜地躺著尖滚,像睡著了一般睦裳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蛛蒙,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天课舍,我揣著相機與錄音,去河邊找鬼筹淫。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蜒什,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疤估!你這毒婦竟也來了霎冯?” 一聲冷哼從身側(cè)響起岗憋,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡凡泣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年皮假,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惹资。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡猴誊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汰扭,到底是詐尸還是另有隱情,我是刑警寧澤福铅,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布笆包,位于F島的核電站环揽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏庵佣。R本人自食惡果不足惜歉胶,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望巴粪。 院中可真熱鬧通今,春花似錦、人聲如沸肛根。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽派哲。三九已至臼氨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芭届,已是汗流浹背储矩。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留褂乍,地道東北人持隧。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像树叽,于是被迫代替她去往敵國和親舆蝴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 索引概念和作用 索引是一種使記錄有序化的技術(shù)题诵,它可以指定按某列/某幾列預(yù)先排序洁仗,從而大大提高查詢速度(類似于漢語詞...
    高級java架構(gòu)師閱讀 1,192評論 0 15
  • 一、mysql數(shù)據(jù)結(jié)構(gòu) Mysql的兩種主要的存儲引擎都依賴的數(shù)據(jù)結(jié)構(gòu)為B+tree性锭,一種從B-tree改進而來的...
    PeTu閱讀 4,765評論 1 16
  • 為什么要使用索引 索引是 MySQL 中一種十分重要的數(shù)據(jù)庫對象赠潦。它是數(shù)據(jù)庫性能調(diào)優(yōu)技術(shù)的基礎(chǔ),常用于實現(xiàn)數(shù)據(jù)的快...
    小波同學(xué)閱讀 289評論 0 2
  • 索引 數(shù)據(jù)庫中的查詢操作非常普遍,索引就是提升查找速度的一種手段 索引的類型 從數(shù)據(jù)結(jié)構(gòu)角度分 1.B+索引:傳統(tǒng)...
    一凡呀閱讀 2,939評論 0 8
  • 看倪萍的一檔節(jié)目怎棱,她分享自己的減肥經(jīng)歷哩俭,講到自己半夜餓得起來找東西吃,但是冰箱里空空如也拳恋,非常有帶入感:想到剛剛開...
    pink_3e1e閱讀 111評論 0 1