1、選擇索引的數(shù)據(jù)類型
MySQL支持很多數(shù)據(jù)類型,選擇合適的數(shù)據(jù)類型存儲(chǔ)數(shù)據(jù)對(duì)性能有很大的影響。通常來(lái)說(shuō),可以遵循以下一些指導(dǎo)原則:
(1)越小的數(shù)據(jù)類型通常更好:越小的數(shù)據(jù)類型通常在磁盤、內(nèi)存和CPU緩存中都需要更少的空間,處理起來(lái)更快。
(2)簡(jiǎn)單的數(shù)據(jù)類型更好:整型數(shù)據(jù)比起字符,處理開(kāi)銷更小,因?yàn)樽址谋容^更復(fù)雜。在MySQL中,應(yīng)該用內(nèi)置的日期和時(shí)間數(shù)據(jù)類型,而不是用字符串來(lái)存儲(chǔ)時(shí)間;以及用整型數(shù)據(jù)類型存儲(chǔ)IP地址。
(3)盡量避免NULL:應(yīng)該指定列為NOT NULL,除非你想存儲(chǔ)NULL。在MySQL中,含有空值的列很難進(jìn)行查詢優(yōu)化,因?yàn)樗鼈兪沟盟饕⑺饕慕y(tǒng)計(jì)信息以及比較運(yùn)算更加復(fù)雜。你應(yīng)該用0、一個(gè)特殊的值或者一個(gè)空串代替空值。
1.1、選擇標(biāo)識(shí)符
選擇合適的標(biāo)識(shí)符是非常重要的。選擇時(shí)不僅應(yīng)該考慮存儲(chǔ)類型,而且應(yīng)該考慮MySQL是怎樣進(jìn)行運(yùn)算和比較的。一旦選定數(shù)據(jù)類型,應(yīng)該保證所有相關(guān)的表都使用相同的數(shù)據(jù)類型。
(1)?? ?整型:通常是作為標(biāo)識(shí)符的最好選擇,因?yàn)榭梢愿斓奶幚恚铱梢栽O(shè)置為AUTO_INCREMENT。
(2)?? ?字符串:盡量避免使用字符串作為標(biāo)識(shí)符,它們消耗更好的空間,處理起來(lái)也較慢。而且,通常來(lái)說(shuō),字符串都是隨機(jī)的,所以它們?cè)谒饕械奈恢靡彩请S機(jī)的,這會(huì)導(dǎo)致頁(yè)面分裂、隨機(jī)訪問(wèn)磁盤,聚簇索引分裂(對(duì)于使用聚簇索引的存儲(chǔ)引擎)。
2、索引入門
對(duì)于任何DBMS,索引都是進(jìn)行優(yōu)化的最主要的因素。對(duì)于少量的數(shù)據(jù),沒(méi)有合適的索引影響不是很大,但是,當(dāng)隨著數(shù)據(jù)量的增加,性能會(huì)急劇下降。
如果對(duì)多列進(jìn)行索引(組合索引),列的順序非常重要,MySQL僅能對(duì)索引最左邊的前綴進(jìn)行有效的查找。例如:
假 設(shè)存在組合索引it1c1c2(c1,c2),查詢語(yǔ)句select * from t1 where c1=1 and c2=2能夠使用該索引。查詢語(yǔ)句select * from t1 where c1=1也能夠使用該索引。但是,查詢語(yǔ)句select * from t1 where c2=2不能夠使用該索引,因?yàn)闆](méi)有組合索引的引導(dǎo)列,即,要想使用c2列進(jìn)行查找,必需出現(xiàn)c1等于某值。
2.1、索引的類型
索引是在存儲(chǔ)引擎中實(shí)現(xiàn)的,而不是在服務(wù)器層中實(shí)現(xiàn)的。所以,每種存儲(chǔ)引擎的索引都不一定完全相同,并不是所有的存儲(chǔ)引擎都支持所有的索引類型。
2.1.1、B-Tree索引
假設(shè)有如下一個(gè)表:
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) );
?其索引包含表中每一行的last_name、first_name和dob列。其結(jié)構(gòu)大致如下:
索引存儲(chǔ)的值按索引列中的順序排列。可以利用B-Tree索引進(jìn)行全關(guān)鍵字、關(guān)鍵字范圍和關(guān)鍵字前綴查詢,當(dāng)然,如果想使用索引,你必須保證按索引的最左邊前綴(leftmost prefix of the index)來(lái)進(jìn)行查詢。
(1)匹配全值(Match the full value):對(duì)索引中的所有列都指定具體的值。例如,上圖中索引可以幫助你查找出生于1960-01-01的Cuba Allen。
(2)匹配最左前綴(Match a leftmost prefix):你可以利用索引查找last name為Allen的人,僅僅使用索引中的第1列。
(3)匹配列前綴(Match a column prefix):例如,你可以利用索引查找last name以J開(kāi)始的人,這僅僅使用索引中的第1列。
(4)匹配值的范圍查詢(Match a range of values):可以利用索引查找last name在Allen和Barrymore之間的人,僅僅使用索引中第1列。
(5)匹配部分精確而其它部分進(jìn)行范圍匹配(Match one part exactly and match a range on another part):可以利用索引查找last name為Allen,而first name以字母K開(kāi)始的人。
(6)僅對(duì)索引進(jìn)行查詢(Index-only queries):如果查詢的列都位于索引中,則不需要讀取元組的值。
由于B-樹(shù)中的節(jié)點(diǎn)都是順序存儲(chǔ)的,所以可以利用索引進(jìn)行查找(找某些值),也可以對(duì)查詢結(jié)果進(jìn)行ORDER BY。當(dāng)然,使用B-tree索引有以下一些限制:
(1) 查詢必須從索引的最左邊的列開(kāi)始。關(guān)于這點(diǎn)已經(jīng)提了很多遍了。例如你不能利用索引查找在某一天出生的人。
(2) 不能跳過(guò)某一索引列。例如,你不能利用索引查找last name為Smith且出生于某一天的人。
(3) 存儲(chǔ)引擎不能使用索引中范圍條件右邊的列。例如,如果你的查詢語(yǔ)句為WHERE last_name=”Smith” AND first_name LIKE ‘J%’ AND dob=’1976-12-23’,則該查詢只會(huì)使用索引中的前兩列,因?yàn)長(zhǎng)IKE是范圍查詢。
以上就是Mysql索引和優(yōu)化的內(nèi)容,更多相關(guān)內(nèi)容請(qǐng)關(guān)注PHP中文網(wǎng)(www.php.cn)!