mysql索引淺析

說(shuō)到索引备蚓,很多人都知道“索引是一個(gè)排序的列表,在這個(gè)列表中存儲(chǔ)著索引的值和包含這個(gè)值的數(shù)據(jù)所在行的物理地址囱稽,在數(shù)據(jù)十分龐大的時(shí)候星著,索引可以大大加快查詢的速度,這是因?yàn)槭褂盟饕罂梢圆挥脪呙枞韥?lái)定位某行的數(shù)據(jù)粗悯,而是先通過(guò)索引表找到該行數(shù)據(jù)對(duì)應(yīng)的物理地址然后訪問(wèn)相應(yīng)的數(shù)據(jù)⊥罚”

但是索引是怎么實(shí)現(xiàn)的呢样傍?因?yàn)樗饕⒉皇顷P(guān)系模型的組成部分横缔,因此不同的DBMS有不同的實(shí)現(xiàn),我們針對(duì)MySQL數(shù)據(jù)庫(kù)的實(shí)現(xiàn)進(jìn)行說(shuō)明衫哥。

一茎刚、MySQL中索引的語(yǔ)法

1、普通索引:

create index on Tablename(列的列表)

alter table TableName add index (列的列表)

create table TableName([...], index [IndexName] (列的列表)

2撤逢、唯一性索引:

create unique index

alter ... add unique

主鍵:一種唯一性索引膛锭,必須指定為primary key

3、全文索引:

從3.23.23版開(kāi)始支持全文索引和全文檢索蚊荣,F(xiàn)ULLTEXT初狰, 可以在char、varchar或text類型的列上創(chuàng)建互例。

4奢入、單列索引、多列索引:

多個(gè)單列索引與單個(gè)多列索引的查詢效果不同媳叨,因?yàn)椋?/p>

執(zhí)行查詢時(shí)腥光,MySQL只能使用一個(gè)索引,會(huì)從多個(gè)索引中選擇一個(gè)限制最為嚴(yán)格的索引糊秆。

5武福、最左前綴(Leftmost Prefixing):

多列索引,例如:fname_lname_age索引痘番,以下的搜索條件MySQL都將使用

fname_lname_age索引:firstname,lastname,age;
firstname,lastname;
firstname捉片,其他情況將不使用。

二夫偶、索引的優(yōu)缺點(diǎn)

  • 優(yōu)勢(shì):可以快速檢索界睁,減少I/O次數(shù),加快檢索速度兵拢;根據(jù)索引分組和排序翻斟,可以加快分組和排序;

  • 劣勢(shì):索引本身也是表说铃,因此會(huì)占用存儲(chǔ)空間访惜,一般來(lái)說(shuō),索引表占用的空間的數(shù)據(jù)表的1.5倍腻扇;索引表的維護(hù)和創(chuàng)建需要時(shí)間成本债热,這個(gè)成本隨著數(shù)據(jù)量增大而增大;構(gòu)建索引會(huì)降低數(shù)據(jù)表的修改操作(刪除幼苛,添加窒篱,修改)的效率,因?yàn)樵谛薷臄?shù)據(jù)表的同時(shí)還需要修改索引表;

三墙杯、索引的分類

常見(jiàn)的索引類型有:主鍵索引配并、唯一索引、普通索引高镐、全文索引溉旋、組合索引

1、主鍵索引:

即主索引嫉髓,根據(jù)主鍵pk_clolum(length)建立索引观腊,不允許重復(fù),不允許空值算行;

ALTER TABLE 'table_name' ADD PRIMARY KEY pk_index('col')梧油;

2、唯一索引:

用來(lái)建立索引的列的值必須是唯一的纱意,允許空值

ALTER TABLE 'table_name' ADD UNIQUE index_name('col')婶溯;

3、普通索引:

用表中的普通列構(gòu)建的索引偷霉,沒(méi)有任何限制

ALTER TABLE 'table_name' ADD INDEX index_name('col')迄委;

4、全文索引:

用大文本對(duì)象的列構(gòu)建的索引(下一部分會(huì)講解)

ALTER TABLE 'table_name' ADD FULLTEXT INDEX ft_index('col')类少;

5菠发、組合索引:

用多個(gè)列組合構(gòu)建的索引图毕,這多個(gè)列中的值不允許有空值

ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3')健田;
遵循“最左前綴”原則泽西,把最常用作為檢索或排序的列放在最左,依次遞減残吩,組合索引相當(dāng)于建立了col1,col1col2,col1col2col3三個(gè)索引财忽,而col2或者col3是不能使用索引的。

在使用組合索引的時(shí)候可能因?yàn)榱忻L(zhǎng)度過(guò)長(zhǎng)而導(dǎo)致索引的key太大泣侮,導(dǎo)致效率降低即彪,在允許的情況下,可以只取col1和col2的前幾個(gè)字符作為索引

ALTER TABLE 'table_name' ADD INDEX index_name(col1(4),col2(3))活尊;
表示使用col1的前4個(gè)字符和col2的前3個(gè)字符作為索引

四隶校、索引的實(shí)現(xiàn)原理

MySQL支持諸多存儲(chǔ)引擎,而各種存儲(chǔ)引擎對(duì)索引的支持也各不相同蛹锰,因此MySQL數(shù)據(jù)庫(kù)支持多種索引類型深胳,如BTree索引,B+Tree索引铜犬,哈希索引舞终,全文索引等等轻庆,

1、哈希索引:

只有memory(內(nèi)存)存儲(chǔ)引擎支持哈希索引权埠,哈希索引用索引列的值計(jì)算該值的hashCode榨了,然后在hashCode相應(yīng)的位置存執(zhí)該值所在行數(shù)據(jù)的物理位置,因?yàn)槭褂蒙⒘兴惴ㄈ帘危虼嗽L問(wèn)速度非常快呐粘,但是一個(gè)值只能對(duì)應(yīng)一個(gè)hashCode满俗,而且是散列的分布方式,因此哈希索引不支持范圍查找和排序的功能作岖。

2唆垃、全文索引:

FULLTEXT(全文)索引,僅可用于MyISAM和InnoDB痘儡,針對(duì)較大的數(shù)據(jù)辕万,生成全文索引非常的消耗時(shí)間和空間。對(duì)于文本的大對(duì)象沉删,或者較大的CHAR類型的數(shù)據(jù)渐尿,如果使用普通索引,那么匹配文本前幾個(gè)字符還是可行的矾瑰,但是想要匹配文本中間的幾個(gè)單詞砖茸,那么就要使用LIKE %word%來(lái)匹配,這樣需要很長(zhǎng)的時(shí)間來(lái)處理殴穴,響應(yīng)時(shí)間會(huì)大大增加凉夯,這種情況,就可使用時(shí)FULLTEXT索引了采幌,在生成FULLTEXT索引時(shí)劲够,會(huì)為文本生成一份單詞的清單,在索引時(shí)及根據(jù)這個(gè)單詞的清單來(lái)索引休傍。FULLTEXT可以在創(chuàng)建表的時(shí)候創(chuàng)建征绎,也可以在需要的時(shí)候用ALTER或者CREATE INDEX來(lái)添加:

//創(chuàng)建表的時(shí)候添加FULLTEXT索引
CTREATE TABLE my_table(
    id INT(10) PRIMARY KEY,
    name VARCHAR(10) NOT NULL,
    my_text TEXT,
    FULLTEXT(my_text)
)ENGINE=MyISAM DEFAULT CHARSET=utf8;
//創(chuàng)建表以后,在需要的時(shí)候添加FULLTEXT索引
ALTER TABLE my_table ADD FULLTEXT INDEX ft_index(column_name);

全文索引的查詢也有自己特殊的語(yǔ)法尊残,而不能使用LIKE %查詢字符串%的模糊查詢語(yǔ)法

SELECT * FROM table_name MATCH(ft_index) AGAINST('查詢字符串');

注意:

  • 對(duì)于較大的數(shù)據(jù)集炒瘸,把數(shù)據(jù)添加到一個(gè)沒(méi)有FULLTEXT索引的表,然后添加FULLTEXT索引的速度比把數(shù)據(jù)添加到一個(gè)已經(jīng)有FULLTEXT索引的表快寝衫。

  • 5.6版本前的MySQL自帶的全文索引只能用于MyISAM存儲(chǔ)引擎顷扩,如果是其它數(shù)據(jù)引擎,那么全文索引不會(huì)生效慰毅。5.6版本之后InnoDB存儲(chǔ)引擎開(kāi)始支持全文索引

  • 在MySQL中隘截,全文索引支隊(duì)英文有用,目前對(duì)中文還不支持。5.7版本之后通過(guò)使用ngram插件開(kāi)始支持中文婶芭。

  • 在MySQL中东臀,如果檢索的字符串太短則無(wú)法檢索得到預(yù)期的結(jié)果,檢索的字符串長(zhǎng)度至少為4字節(jié)犀农,此外惰赋,如果檢索的字符包括停止詞,那么停止詞會(huì)被忽略呵哨。

3赁濒、BTree索引和B+Tree索引

  • BTree索引
    BTree是平衡搜索多叉樹,設(shè)樹的度為2d(d>1)孟害,高度為h拒炎,那么BTree要滿足以一下條件:

  • 每個(gè)葉子結(jié)點(diǎn)的高度一樣,等于h挨务;

  • 每個(gè)非葉子結(jié)點(diǎn)由n-1個(gè)key和n個(gè)指針point組成击你,其中d<=n<=2d,key和point相互間隔,結(jié)點(diǎn)兩端一定是key谎柄;

  • 葉子結(jié)點(diǎn)指針都為null丁侄;

  • 非葉子結(jié)點(diǎn)的key都是[key,data]二元組,其中key表示作為索引的鍵谷誓,data為鍵值所在行的數(shù)據(jù)绒障;

BTree的結(jié)構(gòu)如下:

在BTree的機(jī)構(gòu)下,就可以使用二分查找的查找方式捍歪,查找復(fù)雜度為h*log(n)户辱,一般來(lái)說(shuō)樹的高度是很小的,一般為3左右糙臼,因此BTree是一個(gè)非常高效的查找結(jié)構(gòu)庐镐。

  • B+Tree索引
    B+Tree是BTree的一個(gè)變種,設(shè)d為樹的度數(shù)变逃,h為樹的高度必逆,B+Tree和BTree的不同主要在于:

  • B+Tree中的非葉子結(jié)點(diǎn)不存儲(chǔ)數(shù)據(jù),只存儲(chǔ)鍵值揽乱;

  • B+Tree的葉子結(jié)點(diǎn)沒(méi)有指針名眉,所有鍵值都會(huì)出現(xiàn)在葉子結(jié)點(diǎn)上,且key存儲(chǔ)的鍵值對(duì)應(yīng)data數(shù)據(jù)的物理地址凰棉;

  • B+Tree的每個(gè)非葉子節(jié)點(diǎn)由n個(gè)鍵值key和n個(gè)指針point組成损拢;
    B+Tree的結(jié)構(gòu)如下:

B+Tree對(duì)比BTree的優(yōu)點(diǎn):

  • 1、磁盤讀寫代價(jià)更低

一般來(lái)說(shuō)B+Tree比BTree更適合實(shí)現(xiàn)外存的索引結(jié)構(gòu)撒犀,因?yàn)榇鎯?chǔ)引擎的設(shè)計(jì)專家巧妙的利用了外存(磁盤)的存儲(chǔ)結(jié)構(gòu)福压,即磁盤的最小存儲(chǔ)單位是扇區(qū)(sector)掏秩,而操作系統(tǒng)的塊(block)通常是整數(shù)倍的sector,操作系統(tǒng)以頁(yè)(page)為單位管理內(nèi)存荆姆,一頁(yè)(page)通常默認(rèn)為4K蒙幻,數(shù)據(jù)庫(kù)的頁(yè)通常設(shè)置為操作系統(tǒng)頁(yè)的整數(shù)倍,因此索引結(jié)構(gòu)的節(jié)點(diǎn)被設(shè)計(jì)為一個(gè)頁(yè)的大小胆筒,然后利用外存的“預(yù)讀取”原則邮破,每次讀取的時(shí)候,把整個(gè)節(jié)點(diǎn)的數(shù)據(jù)讀取到內(nèi)存中腐泻,然后在內(nèi)存中查找决乎,已知內(nèi)存的讀取速度是外存讀取I/O速度的幾百倍,那么提升查找速度的關(guān)鍵就在于盡可能少的磁盤I/O派桩,那么可以知道,每個(gè)節(jié)點(diǎn)中的key個(gè)數(shù)越多蚌斩,那么樹的高度越小铆惑,需要I/O的次數(shù)越少,因此一般來(lái)說(shuō)B+Tree比BTree更快送膳,因?yàn)锽+Tree的非葉節(jié)點(diǎn)中不存儲(chǔ)data员魏,就可以存儲(chǔ)更多的key。

  • 2叠聋、查詢速度更穩(wěn)定

由于B+Tree非葉子節(jié)點(diǎn)不存儲(chǔ)數(shù)據(jù)(data)撕阎,因此所有的數(shù)據(jù)都要查詢至葉子節(jié)點(diǎn),而葉子節(jié)點(diǎn)的高度都是相同的碌补,因此所有數(shù)據(jù)的查詢速度都是一樣的虏束。

  • 帶順序索引的B+TREE
    很多存儲(chǔ)引擎在B+Tree的基礎(chǔ)上進(jìn)行了優(yōu)化,添加了指向相鄰葉節(jié)點(diǎn)的指針厦章,形成了帶有順序訪問(wèn)指針的B+Tree镇匀,這樣做是為了提高區(qū)間查找的效率,只要找到第一個(gè)值那么就可以順序的查找后面的值袜啃。

B+Tree的結(jié)構(gòu)如下:


4汗侵、聚簇索引和非聚簇索引

分析了MySQL的索引結(jié)構(gòu)的實(shí)現(xiàn)原理,然后我們來(lái)看看具體的存儲(chǔ)引擎怎么實(shí)現(xiàn)索引結(jié)構(gòu)的群发,MySQL中最常見(jiàn)的兩種存儲(chǔ)引擎分別是MyISAM和InnoDB晰韵,分別實(shí)現(xiàn)了非聚簇索引和聚簇索引。

聚簇索引的解釋是:聚簇索引的順序就是數(shù)據(jù)的物理存儲(chǔ)順序

非聚簇索引的解釋是:索引順序與數(shù)據(jù)物理排列順序無(wú)關(guān)

(這樣說(shuō)起來(lái)并不好理解熟妓,讓人摸不著頭腦雪猪,清繼續(xù)看下文,并在插圖下方對(duì)上述兩句話有解釋)

首先要介紹幾個(gè)概念滑蚯,在索引的分類中浪蹂,我們可以按照索引的鍵是否為主鍵來(lái)分為“主索引”和“輔助索引”抵栈,使用主鍵鍵值建立的索引稱為“主索引”,其它的稱為“輔助索引”坤次。因此主索引只能有一個(gè)古劲,輔助索引可以有很多個(gè)。

MyISAM——非聚簇索引
  • MyISAM存儲(chǔ)引擎采用的是非聚簇索引缰猴,非聚簇索引的主索引和輔助索引幾乎是一樣的产艾,只是主索引不允許重復(fù),不允許空值滑绒,他們的葉子結(jié)點(diǎn)的key都存儲(chǔ)指向鍵值對(duì)應(yīng)的數(shù)據(jù)的物理地址闷堡。
  • 非聚簇索引的數(shù)據(jù)表和索引表是分開(kāi)存儲(chǔ)的。
  • 非聚簇索引中的數(shù)據(jù)是根據(jù)數(shù)據(jù)的插入順序保存疑故。因此非聚簇索引更適合單個(gè)數(shù)據(jù)的查詢杠览。插入順序不受鍵值影響。
  • 只有在MyISAM中才能使用FULLTEXT索引纵势。(mysql5.6以后innoDB也支持全文索引)

最開(kāi)始我一直不懂既然非聚簇索引的主索引和輔助索引指向相同的內(nèi)容踱阿,為什么還要輔助索引這個(gè)東西呢,后來(lái)才明白索引不就是用來(lái)查詢的嗎钦铁,用在那些地方呢软舌,不就是WHERE和ORDER BY 語(yǔ)句后面嗎,那么如果查詢的條件不是主鍵怎么辦呢牛曹,這個(gè)時(shí)候就需要輔助索引了佛点。

InnoDB——聚簇索引
  • 聚簇索引的主索引的葉子結(jié)點(diǎn)存儲(chǔ)的是鍵值對(duì)應(yīng)的數(shù)據(jù)本身,輔助索引的葉子結(jié)點(diǎn)存儲(chǔ)的是鍵值對(duì)應(yīng)的數(shù)據(jù)的主鍵鍵值黎比。因此主鍵的值長(zhǎng)度越小越好超营,類型越簡(jiǎn)單越好。
  • 聚簇索引的數(shù)據(jù)和主鍵索引存儲(chǔ)在一起焰手。
  • 聚簇索引的數(shù)據(jù)是根據(jù)主鍵的順序保存糟描。因此適合按主鍵索引的區(qū)間查找,可以有更少的磁盤I/O书妻,加快查詢速度船响。但是也是因?yàn)檫@個(gè)原因,聚簇索引的插入順序最好按照主鍵單調(diào)的順序插入躲履,否則會(huì)頻繁的引起頁(yè)分裂见间,嚴(yán)重影響性能。
  • 在InnoDB中工猜,如果只需要查找索引的列米诉,就盡量不要加入其它的列,這樣會(huì)提高查詢效率篷帅。

使用主索引的時(shí)候史侣,更適合使用聚簇索引拴泌,因?yàn)榫鄞厮饕恍枰檎乙淮危蔷鄞厮饕诓榈綌?shù)據(jù)的地址后惊橱,還要進(jìn)行一次I/O查找數(shù)據(jù)蚪腐。

因?yàn)榫鄞剌o助索引存儲(chǔ)的是主鍵的鍵值,因此可以在數(shù)據(jù)行移動(dòng)或者頁(yè)分裂的時(shí)候降低成本税朴,因?yàn)檫@時(shí)不用維護(hù)輔助索引回季。但是由于主索引存儲(chǔ)的是數(shù)據(jù)本身,因此聚簇索引會(huì)占用更多的空間正林。

聚簇索引在插入新數(shù)據(jù)的時(shí)候比非聚簇索引慢很多泡一,因?yàn)椴迦胄聰?shù)據(jù)時(shí)需要檢測(cè)主鍵是否重復(fù),這需要遍歷主索引的所有葉節(jié)點(diǎn)觅廓,而非聚簇索引的葉節(jié)點(diǎn)保存的是數(shù)據(jù)地址鼻忠,占用空間少,因此分布集中杈绸,查詢的時(shí)候I/O更少粥烁,但聚簇索引的主索引中存儲(chǔ)的是數(shù)據(jù)本身,數(shù)據(jù)占用空間大蝇棉,分布范圍更大,可能占用好多的扇區(qū)芥永,因此需要更多次I/O才能遍歷完畢篡殷。

下圖可以形象的說(shuō)明聚簇索引和非聚簇索引的區(qū)別


從上圖中可以看到聚簇索引的輔助索引的葉子節(jié)點(diǎn)的data存儲(chǔ)的是主鍵的值,主索引的葉子節(jié)點(diǎn)的data存儲(chǔ)的是數(shù)據(jù)本身埋涧,也就是說(shuō)數(shù)據(jù)和索引存儲(chǔ)在一起板辽,并且索引查詢到的地方就是數(shù)據(jù)(data)本身,那么索引的順序和數(shù)據(jù)本身的順序就是相同的棘催;

而非聚簇索引的主索引和輔助索引的葉子節(jié)點(diǎn)的data都是存儲(chǔ)的數(shù)據(jù)的物理地址劲弦,也就是說(shuō)索引和數(shù)據(jù)并不是存儲(chǔ)在一起的,數(shù)據(jù)的順序和索引的順序并沒(méi)有任何關(guān)系醇坝,也就是索引順序與數(shù)據(jù)物理排列順序無(wú)關(guān)邑跪。

此外MyISAM和innoDB的區(qū)別總結(jié)如下:

MyISAM innoDB
索引類型 非聚簇 聚簇
支持事務(wù)
支持表鎖
支持行鎖 是(默認(rèn))
支持外鍵
支持全文索引 是(5.6以后支持)
使用操作類型 大量select下使用 大量insert、update呼猪、delete下使用

總結(jié)如下:

  • InnoDB 支持事務(wù)画畅,支持行級(jí)別鎖定,支持 B-tree宋距、Full-text 等索引轴踱,不支持 Hash 索引;
  • MyISAM 不支持事務(wù)谚赎,支持表級(jí)別鎖定淫僻,支持 B-tree诱篷、Full-text 等索引,不支持 Hash 索引雳灵;
    此外棕所,Memory 不支持事務(wù),支持表級(jí)別鎖定细办,支持 B-tree橙凳、Hash 等索引,不支持 Full-text 索引笑撞;

五岛啸、索引的使用策略

什么時(shí)候要使用索引?

  • 主鍵自動(dòng)建立唯一索引茴肥;
  • 經(jīng)常作為查詢條件在WHERE或者ORDER BY 語(yǔ)句中出現(xiàn)的列要建立索引坚踩;
  • 作為排序的列要建立索引;
  • 查詢中與其他表關(guān)聯(lián)的字段瓤狐,外鍵關(guān)系建立索引
  • 高并發(fā)條件下傾向組合索引瞬铸;
  • 用于聚合函數(shù)的列可以建立索引,例如使用了max(column_1)或者count(column_1)時(shí)的column_1就需要建立索引

什么時(shí)候不要使用索引础锐?

  • 經(jīng)常增刪改的列不要建立索引嗓节;
  • 有大量重復(fù)的列不建立索引;
  • 表記錄太少不要建立索引皆警。只有當(dāng)數(shù)據(jù)庫(kù)里已經(jīng)有了足夠多的測(cè)試數(shù)據(jù)時(shí)拦宣,它的性能測(cè)試結(jié)果才有實(shí)際參考價(jià)值。如果在測(cè)試數(shù)據(jù)庫(kù)里只有幾百條數(shù)據(jù)記錄信姓,它們往往在執(zhí)行完第一條查詢命令之后就被全部加載到內(nèi)存里鸵隧,這將使后續(xù)的查詢命令都執(zhí)行得非常快--不管有沒(méi)有使用索引意推。只有當(dāng)數(shù)據(jù)庫(kù)里的記錄超過(guò)了1000條豆瘫、數(shù)據(jù)總量也超過(guò)了MySQL服務(wù)器上的內(nèi)存總量時(shí),數(shù)據(jù)庫(kù)的性能測(cè)試結(jié)果才有意義菊值。

索引失效的情況:

  • 在組合索引中不能有列的值為NULL外驱,如果有,那么這一列對(duì)組合索引就是無(wú)效的俊性。
  • 在一個(gè)SELECT語(yǔ)句中略步,索引只能使用一次,如果在WHERE中使用了定页,那么在ORDER BY中就不要用了趟薄。
  • LIKE操作中,'%aaa%'不會(huì)使用索引典徊,也就是索引會(huì)失效杭煎,但是‘a(chǎn)aa%’可以使用索引恩够。
  • 在索引的列上使用表達(dá)式或者函數(shù)會(huì)使索引失效,例如:select * from users where YEAR(adddate)<2007羡铲,將在每個(gè)行上進(jìn)行運(yùn)算蜂桶,這將導(dǎo)致索引失效而進(jìn)行全表掃描,因此我們可以改成:select * from users where adddate<’2007-01-01′也切。其它通配符同樣扑媚,也就是說(shuō),在查詢條件中使用正則表達(dá)式時(shí)雷恃,只有在搜索模板的第一個(gè)字符不是通配符的情況下才能使用索引疆股。
  • 在查詢條件中使用不等于,包括<符號(hào)倒槐、>符號(hào)和旬痹!=會(huì)導(dǎo)致索引失效。特別的是如果對(duì)主鍵索引使用讨越!=則不會(huì)使索引失效两残,如果對(duì)主鍵索引或者整數(shù)類型的索引使用<符號(hào)或者>符號(hào)不會(huì)使索引失效。(經(jīng)erwkjrfhjwkdb同學(xué)提醒把跨,不等于人弓,包括<符號(hào)、>符號(hào)和着逐!票从,如果占總記錄的比例很小的話,也不會(huì)失效)
  • 在查詢條件中使用IS NULL或者IS NOT NULL會(huì)導(dǎo)致索引失效滨嘱。
  • 字符串不加單引號(hào)會(huì)導(dǎo)致索引失效。更準(zhǔn)確的說(shuō)是類型不一致會(huì)導(dǎo)致失效浸间,比如字段email是字符串類型的太雨,使用WHERE email=99999 則會(huì)導(dǎo)致失敗,應(yīng)該改為WHERE email='99999'魁蒜。
  • 在查詢條件中使用OR連接多個(gè)條件會(huì)導(dǎo)致索引失效囊扳,除非OR鏈接的每個(gè)條件都加上索引,這時(shí)應(yīng)該改為兩次查詢兜看,然后用UNION ALL連接起來(lái)锥咸。
  • 如果排序的字段使用了索引,那么select的字段也要是索引字段细移,否則索引失效搏予。特別的是如果排序的是主鍵索引則select * 也不會(huì)導(dǎo)致索引失效。
  • 盡量不要包括多列排序弧轧,如果一定要雪侥,最好為這隊(duì)列構(gòu)建組合索引碗殷;

六、索引的優(yōu)化

1速缨、最左前綴

索引的最左前綴和和B+Tree中的“最左前綴原理”有關(guān)锌妻,舉例來(lái)說(shuō)就是如果設(shè)置了組合索引<col1,col2,col3>那么以下3中情況可以使用索引:col1,<col1,col2>旬牲,<col1,col2,col3>仿粹,其它的列,比如<col2,col3>原茅,<col1,col3>吭历,col2,col3等等都是不能使用索引的员咽。

根據(jù)最左前綴原則毒涧,我們一般把排序分組頻率最高的列放在最左邊,以此類推贝室。

2契讲、帶索引的模糊查詢優(yōu)化

在上面已經(jīng)提到,使用LIKE進(jìn)行模糊查詢的時(shí)候滑频,'%aaa%'不會(huì)使用索引捡偏,也就是索引會(huì)失效。如果是這種情況峡迷,只能使用全文索引來(lái)進(jìn)行優(yōu)化(上文有講到)银伟。

3、為檢索的條件構(gòu)建全文索引绘搞,然后使用

SELECT * FROM tablename MATCH(index_colum) ANGAINST(‘word’);

4彤避、使用短索引

對(duì)串列進(jìn)行索引,如果可能應(yīng)該指定一個(gè)前綴長(zhǎng)度夯辖。例如琉预,如果有一個(gè)CHAR(255)的 列,如果在前10 個(gè)或20 個(gè)字符內(nèi)蒿褂,多數(shù)值是惟一的圆米,那么就不要對(duì)整個(gè)列進(jìn)行索引。短索引不僅可以提高查詢速度而且可以節(jié)省磁盤空間和I/O操作啄栓。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末娄帖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子昙楚,更是在濱河造成了極大的恐慌近速,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異数焊,居然都是意外死亡永淌,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門佩耳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)遂蛀,“玉大人,你說(shuō)我怎么就攤上這事干厚±畹危” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵蛮瞄,是天一觀的道長(zhǎng)所坯。 經(jīng)常有香客問(wèn)我,道長(zhǎng)挂捅,這世上最難降的妖魔是什么芹助? 我笑而不...
    開(kāi)封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮闲先,結(jié)果婚禮上状土,老公的妹妹穿的比我還像新娘。我一直安慰自己伺糠,他們只是感情好蒙谓,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著训桶,像睡著了一般累驮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舵揭,一...
    開(kāi)封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天谤专,我揣著相機(jī)與錄音,去河邊找鬼午绳。 笑死毒租,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的箱叁。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼惕医,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耕漱!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起抬伺,我...
    開(kāi)封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤螟够,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妓笙,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡若河,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寞宫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片萧福。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖辈赋,靈堂內(nèi)的尸體忽然破棺而出鲫忍,到底是詐尸還是另有隱情,我是刑警寧澤钥屈,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布悟民,位于F島的核電站,受9級(jí)特大地震影響篷就,放射性物質(zhì)發(fā)生泄漏射亏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一竭业、第九天 我趴在偏房一處隱蔽的房頂上張望智润。 院中可真熱鬧,春花似錦永品、人聲如沸做鹰。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)钾麸。三九已至,卻和暖如春炕桨,著一層夾襖步出監(jiān)牢的瞬間饭尝,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工献宫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钥平,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓姊途,卻偏偏與公主長(zhǎng)得像涉瘾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捷兰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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

  • 一立叛、索引是做什么的? 很多時(shí)候,當(dāng)你的應(yīng)用程序進(jìn)行SQL查詢速度很慢時(shí)贡茅,應(yīng)該想想是否可以建索引秘蛇。 大多數(shù)MySQL...
    wuxiumu閱讀 425評(píng)論 0 1
  • 索引 數(shù)據(jù)庫(kù)中的查詢操作非常普遍赁还,索引就是提升查找速度的一種手段 索引的類型 從數(shù)據(jù)結(jié)構(gòu)角度分 1.B+索引:傳統(tǒng)...
    一凡呀閱讀 2,879評(píng)論 0 8
  • 聚簇索引并不是一種單獨(dú)的索引類型妖泄,而是一種數(shù)據(jù)存儲(chǔ)方式。比如艘策,InnoDB的聚簇索引使用B+Tree的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)...
    sherlock_6981閱讀 1,859評(píng)論 0 2
  • 轉(zhuǎn)載:http://blog.codinglabs.org/articles/theory-of-mysql-in...
    qf1007閱讀 1,287評(píng)論 0 0
  • 先來(lái)看個(gè)問(wèn)題 假設(shè)現(xiàn)在有100000條從0到10000且從大到小排列的整型數(shù)據(jù)蹈胡,1條數(shù)據(jù)的大小假設(shè)(真的只是假設(shè))...
    kindol閱讀 526評(píng)論 0 2