在上一篇文章 MySQL 基礎(chǔ)語(yǔ)法 中,我們說(shuō)過(guò)如果使用了 LIKE + % 開(kāi)頭,就索引會(huì)失效,那么當(dāng)我們需要前后都模糊搜索的需求(如 LIKE ‘%hello%’),就需要使用全文索引,需要注意的是,Innodb 只有在 5.6 版本之后才支持全文索引。
全文索引的創(chuàng)建和刪除:
# 創(chuàng)建的兩種方法
CREATE FULLTEXT INDEX idx_name ON tbl_name(field_name);
ALTER TABLE tbl_name ADD FULLTEXT INDEX idx_name(field_name);
# 刪除的兩種方法
DROP INDEX idx_name ON tbl_name;
ALTER TABLE tbl_name DROP INDEX idx_name;
使用全文索引進(jìn)行全模糊匹配的語(yǔ)法為:
SELECT XXX FROM tbl_name WHERE match(field_name) against('xxx');
# 比如對(duì) user_tbl 的 user_name 字段加了全文索引
# 查詢(xún)結(jié)果等效于 SELECT user_name, user_id FROM user_tbl WHERE user_name LIKE '%hello%';
SELECT user_name, user_id FROM user_tbl WHERE match(user_name) against('hello');
WHERE x = 1WHERE x = 1 AND y = 1WHERE x = 1 AND y = 1 AND z = 1
對(duì)于其他情況,比如 WHERE y = 1 、WHERE y = 1 AND z = 1 等,就不會(huì)匹配聯(lián)合索引,索引失效,注意對(duì)于 WHERE x = 1 AND z = 1,聯(lián)合索引會(huì)對(duì) x 生效,但是對(duì) z 不生效。
可以擴(kuò)展了解一下,理論上最左匹配原則中索引對(duì) where 中子句的順序也是敏感的,但是由于MySQL的查詢(xún)優(yōu)化器會(huì)自動(dòng)調(diào)整 where 子句的條件順序以使用適合的索引,所以實(shí)際上 where 子句順序不影響索引的效果。
要注意的是,如果聯(lián)合索引查詢(xún)過(guò)程中有范圍查詢(xún),就會(huì)停止匹配,比如下面的語(yǔ)句中, z 字段不能使用到索引:
如果分別在 x, y, z 上建立單列索引,讓該表有3個(gè)單列索引,索引效率也會(huì)大不一樣,在聯(lián)合索引生效的情況下,單個(gè)索引的效率遠(yuǎn)遠(yuǎn)低于聯(lián)合索引。這是由 MySQL 查詢(xún)優(yōu)化器的執(zhí)行順序決定的,在執(zhí)行一條查詢(xún) sql 時(shí),針對(duì)索引的選擇大致有如下步驟:
MySQL 優(yōu)化器根據(jù)搜索條件,找出所有可能使用的索引
計(jì)算全表掃描的代價(jià)
計(jì)算使用不同索引執(zhí)行查詢(xún)的代價(jià)
對(duì)比各種執(zhí)行方案的代價(jià),找出成本最低的那一個(gè)
因此,雖然有多個(gè)單列索引,但 MySQL 只能用到其中的那個(gè)系統(tǒng)認(rèn)為似乎是最有效率的,其他的就會(huì)失效。
按索引結(jié)構(gòu)劃分
不同的 mysql 數(shù)據(jù)引擎支持不同結(jié)構(gòu)的索引,按結(jié)構(gòu)劃分,常用的索引為 B+樹(shù)索引、Hash 索引、FULLTEXT索引 等,將在下一篇文章 MySQL 索引結(jié)構(gòu) 中介紹。
多個(gè)單列索引在多條件查詢(xún)是只會(huì)有一個(gè)最優(yōu)的索引生效,因此多條件查詢(xún)中最好創(chuàng)建聯(lián)合索引。聯(lián)合索引的時(shí)候必須滿(mǎn)足最左匹配原則,并且最好考慮到 sql 語(yǔ)句的執(zhí)行順序,比如 WHERE a = 1 GROUP BY b ORDER BY c, 那么聯(lián)合索引應(yīng)該設(shè)計(jì)為 (a,b,c),因?yàn)樵谏弦黄恼?MySQL 基礎(chǔ)語(yǔ)法 中我們介紹過(guò),mysql 查詢(xún)語(yǔ)句的執(zhí)行順序 WHERE > GROUP BY > ORDER BY。