mysql索引创建和使用注意事项
總結(jié):
1、在使用索引時(shí),一般情況下不建議使用like操作。如果使用,則%放在后面。否則不會使用索引。like ‘%abd%’不會使用索引,而like ‘a(chǎn)aa%’可以使用索引.(最左綴原則)
2、單列索引的使用:
《1》 只涉及到其中一個(gè)字段時(shí),都能使用到索引
《2》模糊查詢時(shí),%如果在前面,那么不會使用索引
《3》涉及到多個(gè)索引字段時(shí),如果這些索引字段中,存在主鍵索引,那么只會使用該索引
《4》涉及到多個(gè)索引字段時(shí),如果這些索引字段中,不存在主鍵索引的話,那么就會使用該使用的索引(注:如果通過其中的部分索引就能準(zhǔn)確定位的話,那么其余的索引就不再被使用)
《5》當(dāng)對索引字段進(jìn)行?>,?<,>=,?<=,not in,between …… and ……,函數(shù)(索引字段),like模糊查詢%在字段前時(shí),不會使用該索引
4、組合索引的使用:
最左原則:
???????假設(shè)組合索引為:a,b,c的話;那么當(dāng)SQL中對應(yīng)有:a或a,b或a,b,c的時(shí)候,可稱為完全滿足最左原則;當(dāng)SQL中對應(yīng)只有a,c的時(shí)候,可稱為部分滿足最左原則;當(dāng)SQL中沒有a的時(shí)候,可稱為不滿足最左原則。
注:SQL語句中的對應(yīng)條件的先后順序無關(guān)。
《1》當(dāng)完全滿足最左原則時(shí),所有字段都會使用組合索引
《2》當(dāng)部分滿足最左原則時(shí),只有a字段會使用組合索引(a,c 中只有a會使用組合索引)
《3》當(dāng)不滿足最左原則時(shí),不使用組合索引
《4》滿足(部分滿足)最左原則的字段里,有字段不滿足“索引”自身的使用規(guī)范:
? ? ? ? ? ?說明:如果SQL語句里的字段里,滿足了最左原則,但是不滿足“索引”自身的使用規(guī)范,那么組合索引走到這里之后,
? ? ? ? ? ?不會再往下走了
索引的創(chuàng)建:
建表時(shí)創(chuàng)建:
CREATE TABLE 表名(
字段名 數(shù)據(jù)類型 [完整性約束條件],
???????……,
[UNIQUE | FULLTEXT | SPATIAL] INDEX | KEY
[索引名](字段名1 [(長度)] [ASC | DESC]) [USING 索引方法]
);
說明:
- UNIQUE:可選。表示索引為唯一性索引。
- FULLTEXT:可選。表示索引為全文索引。
- SPATIAL:可選。表示索引為空間索引。
- INDEX和KEY:用于指定字段為索引,兩者選擇其中之一就可以了,作用是 ???一樣的。
- 索引名:可選。給創(chuàng)建的索引取一個(gè)新名稱。
- 字段名1:指定索引對應(yīng)的字段的名稱,該字段必須是前面定義好的字段。
- 長度:可選。指索引的長度,必須是字符串類型才可以使用。
- ASC:可選。表示升序排列。
- DESC:可選。表示降序排列。
注:索引方法默認(rèn)使用BTREE。
單列索引(示例):
CREATE TABLE projectfile (id INT AUTO_INCREMENT COMMENT '附件id',fileuploadercode VARCHAR(128) COMMENT '附件上傳者code',projectid INT COMMENT '項(xiàng)目id;此列受project表中的id列約束',filename VARCHAR (512) COMMENT '附件名',fileurl VARCHAR (512) COMMENT '附件下載地址',filesize BIGINT COMMENT '附件大小,單位Byte',-- 主鍵本身也是一種索引(注:也可以在上面的創(chuàng)建字段時(shí)使該字段主鍵自增)PRIMARY KEY (id),-- 主外鍵約束(注:project表中的id字段約束了此表中的projectid字段)FOREIGN KEY (projectid) REFERENCES project (id),-- 給projectid字段創(chuàng)建了唯一索引(注:也可以在上面的創(chuàng)建字段時(shí)使用unique來創(chuàng)建唯一索引)UNIQUE INDEX (projectid),-- 給fileuploadercode字段創(chuàng)建普通索引INDEX (fileuploadercode)-- 指定使用INNODB存儲引擎(該引擎支持事務(wù))、utf8字符編碼 ) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT '項(xiàng)目附件表';注:這里只為示例如何創(chuàng)建索引,其他的合理性之類的先放一邊。
組合索引(示例):
CREATE TABLE projectfile (id INT AUTO_INCREMENT COMMENT '附件id',fileuploadercode VARCHAR(128) COMMENT '附件上傳者code',projectid INT COMMENT '項(xiàng)目id;此列受project表中的id列約束',filename VARCHAR (512) COMMENT '附件名',fileurl VARCHAR (512) COMMENT '附件下載地址',filesize BIGINT COMMENT '附件大小,單位Byte',-- 主鍵本身也是一種索引(注:也可以在上面的創(chuàng)建字段時(shí)使該字段主鍵自增)PRIMARY KEY (id),-- 創(chuàng)建組合索引INDEX (fileuploadercode,projectid)-- 指定使用INNODB存儲引擎(該引擎支持事務(wù))、utf8字符編碼 ) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT '項(xiàng)目附件表';
建表后創(chuàng)建:
ALTER?TABLE?表名?ADD?[UNIQUE | FULLTEXT | SPATIAL]??INDEX | KEY??[索引名]?(字段名1 [(長度)] [ASC | DESC])?[USING 索引方法];
或
CREATE??[UNIQUE | FULLTEXT | SPATIAL]??INDEX??索引名?ON??表名(字段名)?[USING 索引方法]
示例一:
-- 假設(shè)建表時(shí)fileuploadercode字段沒創(chuàng)建索引(注:同一個(gè)字段可以創(chuàng)建多個(gè)索引,但一般情況下意義不大) -- 給projectfile表中的fileuploadercode創(chuàng)建索引 ALTER TABLE projectfile ADD UNIQUE INDEX (fileuploadercode);
示例二:
示例三:
查看已創(chuàng)建的索引:
show index from 表名;
提示:我們也可以直接使用工具查看
示例:
索引的刪除:
DROP INDEX 索引名 ON 表名
或
ALTER TABLE 表名 DROP INDEX?索引名
示例一:
drop index fileuploadercode1 on projectfile;
示例二:
alter table projectfile drop index s2123;
查看SQL語句對索引的使用情況(即:查詢SQL的查詢執(zhí)行計(jì)劃QEP):
在select語句前加上EXPLAIN即可。
示例:
EXPLAIN SELECT * FROM `index_demo` ii WHERE ii.e_name = 'Jane';
分析該SQL的性能為:
提示:我們也可以使用SQL工具查看,如:navicat中的“解釋”選項(xiàng)即可查看。
說明:
id:SELECT識別符。這是SELECT的查詢序列號。
select_type:SELECT類型。
SIMPLE: 簡單SELECT(不使用UNION或子查詢)
PRIMARY: 最外面的SELECT
UNION:UNION中的第二個(gè)或后面的SELECT語句
DEPENDENT UNION:UNION中的第二個(gè)或后面的SELECT語句,取決于外面的查詢
UNION RESULT:UNION的結(jié)果
SUBQUERY:子查詢中的第一個(gè)SELECT
DEPENDENT SUBQUERY:子查詢中的第一個(gè)SELECT,取決于外面的查詢
DERIVED:導(dǎo)出表的SELECT(FROM子句的子查詢)
table:表名
type:聯(lián)接類型。是SQL性能的非常重要的一個(gè)指標(biāo),結(jié)果值從好到壞依次是:system > const > eq_ref > ref
????????????> fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL。
????????????一般來說,得保證查詢至少達(dá)到range級別。
system:表僅有一行(=系統(tǒng)表)。這是const聯(lián)接類型的一個(gè)特例。
const:表最多有一個(gè)匹配行,它將在查詢開始時(shí)被讀取。因?yàn)閮H有一行,在這行的列值可被優(yōu)化器剩余部分認(rèn)為是常數(shù)。const用于用常數(shù)值比較PRIMARY KEY或UNIQUE索引的所有部分時(shí)。
eq_ref:對于每個(gè)來自于前面的表的行組合,從該表中讀取一行。這可能是最好的聯(lián)接類型,除了const類型。它用在一個(gè)索引的所有部分被聯(lián)接使用并且索引是UNIQUE或PRIMARY KEY。eq_ref可以用于使用= 操作符比較的帶索引的列。比較值可以為常量或一個(gè)使用在該表前面所讀取的表的列的表達(dá)式。
ref:對于每個(gè)來自于前面的表的行組合,所有有匹配索引值的行將從這張表中讀取。如果聯(lián)接只使用鍵的最左邊的前綴,或如果鍵不是UNIQUE或PRIMARY KEY(換句話說,如果聯(lián)接不能基于關(guān)鍵字選擇單個(gè)行的話),則使用ref。如果使用的鍵僅僅匹配少量行,該聯(lián)接類型是不錯(cuò)的。ref可以用于使用=或<=>操作符的帶索引的列。
ref_or_null:該聯(lián)接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行。在解決子查詢中經(jīng)常使用該聯(lián)接類型的優(yōu)化。
index_merge:該聯(lián)接類型表示使用了索引合并優(yōu)化方法。在這種情況下,key列包含了使用的索引的清單,key_len包含了使用的索引的最長的關(guān)鍵元素。
unique_subquery:該類型替換了下面形式的IN子查詢的ref:value IN (SELECT primary_key FROMsingle_table WHERE some_expr);unique_subquery是一個(gè)索引查找函數(shù),可以完全替換子查詢,效率更高。
index_subquery:該聯(lián)接類型類似于unique_subquery。可以替換IN子查詢,但只適合下列形式的子查詢中的非唯一索引:value IN (SELECT key_column FROM single_table WHERE some_expr)
range:只檢索給定范圍的行,使用一個(gè)索引來選擇行。key列顯示使用了哪個(gè)索引。key_len包含所使用索引的最長關(guān)鍵元素。在該類型中ref列為NULL。當(dāng)使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比較關(guān)鍵字列時(shí),可以使用range
index:該聯(lián)接類型與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因?yàn)樗饕募ǔ1葦?shù)據(jù)文件小。
all:對于每個(gè)來自于先前的表的行組合,進(jìn)行完整的表掃描。如果表是第一個(gè)沒標(biāo)記const的表,這通常不好,并且通常在它情況下很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常數(shù)值或列值被檢索出。
possible_keys:possible_keys列指出MySQL能使用哪個(gè)索引在該表中找到行。注意,該列完全獨(dú)立于EXPLAIN輸出所示的表的次序。這意味著在possible_keys中的某些鍵實(shí)際上不能按生成的表次序使用。
key:key列顯示MySQL實(shí)際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL。要想強(qiáng)制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
key_len:key_len列顯示MySQL決定使用的鍵長度。如果鍵是NULL,則長度為NULL。注意通過key_len值我們可以確定MySQL將實(shí)際使用一個(gè)多部關(guān)鍵字的幾個(gè)部分。
ref:ref列顯示使用哪個(gè)列或常數(shù)與key一起從表中選擇行。
rows:rows列顯示MySQL認(rèn)為它執(zhí)行查詢時(shí)必須檢查的行數(shù)。
Extra:該列包含MySQL解決查詢的詳細(xì)信息。
Distinct:MySQL發(fā)現(xiàn)第1個(gè)匹配行后,停止為當(dāng)前的行組合搜索更多的行。
Not exists:MySQL能夠?qū)Σ樵冞M(jìn)行LEFT JOIN優(yōu)化,發(fā)現(xiàn)1個(gè)匹配LEFT JOIN標(biāo)準(zhǔn)的行后,不再為前面的的行組合在該表內(nèi)檢查更多的行。
range checked for each record (index map: #):MySQL沒有發(fā)現(xiàn)好的可以使用的索引,但發(fā)現(xiàn)如果來自前面的表的列值已知,可能部分索引可以使用。對前面的表的每個(gè)行組合,MySQL檢查是否可以使用range或index_merge訪問方法來索取行。
Using filesort:MySQL需要額外的一次傳遞,以找出如何按排序順序檢索行。通過根據(jù)聯(lián)接類型瀏覽所有行并為所有匹配WHERE子句的行保存排序關(guān)鍵字和行的指針來完成排序。然后關(guān)鍵字被排序,并按排序順序檢索行。
Using index:從只使用索引樹中的信息而不需要進(jìn)一步搜索讀取實(shí)際的行來檢索表中的列信息。當(dāng)查詢只使用作為單一索引一部分的列時(shí),可以使用該策略。
Using temporary:為了解決查詢,MySQL需要?jiǎng)?chuàng)建一個(gè)臨時(shí)表來容納結(jié)果。典型情況如查詢包含可以按不同情況列出列的GROUP BY和ORDER BY子句時(shí)。
Using where:WHERE子句用于限制哪一個(gè)行匹配下一個(gè)表或發(fā)送到客戶。除非你專門從表中索取或檢查所有行,如果Extra值不為Using where并且表聯(lián)接類型為ALL或index,查詢可能會有一些錯(cuò)誤。
Using sort_union(...), Using union(...), Using intersect(...):這些函數(shù)說明如何為index_merge聯(lián)接類型合并索引掃描。
Using index for group-by:類似于訪問表的Using index方式,Using index for group-by表示MySQL發(fā)現(xiàn)了一個(gè)索引,可以用來查詢GROUP BY或DISTINCT查詢的所有列,而不要額外搜索硬盤訪問實(shí)際的表。并且,按最有效的方式使用索引,以便對于每個(gè)組,只讀取少量索引條目。
單列索引的使用:
準(zhǔn)備工作:
給id加主鍵索引:
再分別給name、city、country、address加上普通索引:
注:以上五個(gè)索引都是單列索引。
使用情況:
只涉及到其中的一個(gè)字段時(shí),都能使用到索引(以e_name為例):
?
注:模糊查詢時(shí),%如果在前面,那么不會使用索引。
涉及到多個(gè)索引字段時(shí),如果這些索引字段中,存在主鍵索引,那么只會使用該索引(即:MYSQL優(yōu)化器會選出并先執(zhí)行最“嚴(yán)”的索引):
提示:possible_key中,只是SQL語句里涉及到的索引;key中才是實(shí)際上執(zhí)行查詢操作時(shí)使用到了的索引。
涉及到多個(gè)索引字段時(shí),如果這些索引字段中,不存在主鍵索引的話,那么就會使用該使用的索引(注:如果通過其中的部分索引就能準(zhǔn)確定位的話,那么其余的索引就不再被使用):
?
注:多個(gè)索引時(shí),先使用哪個(gè)索引后使用哪個(gè)索引,是由MySQL的優(yōu)化器經(jīng)過一些列計(jì)算后作出的抉擇。
當(dāng)對索引字段進(jìn)行?>,?<,>=, <=,not in,between …… and ……,函數(shù)(索引字段),like模糊查詢%在字段前時(shí),不會使用該索引
注:這里對e_age字段進(jìn)行了 “<” ,所以實(shí)際查詢時(shí),并沒有使用e_age的索引。
提示:在實(shí)際使用時(shí),如果涉及到多列,我們一般都不會將這些列一 一創(chuàng)建為單列索引,而是將這些列創(chuàng)建為組合索引。
組合索引的使用:
最左原則:
???????假設(shè)組合索引為:a,b,c的話;那么當(dāng)SQL中對應(yīng)有:a或a,b或a,b,c的時(shí)候,可稱為完全滿足最左原則;當(dāng)SQL中對應(yīng)只有a,c的時(shí)候,可稱為部分滿足最左原則;當(dāng)SQL中沒有a的時(shí)候,可稱為不滿足最左原則。
注:SQL語句中的對應(yīng)條件的先后順序無關(guān)。
索引”自身的使用規(guī)范,那么當(dāng)“e_name”走完組合索引后,
??????????????????走到“e_age”時(shí),該字段及其后面的字段不會再走組合索引了。?
? ? ? ??
?
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的mysql索引创建和使用注意事项的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SVM理论学习记忆
- 下一篇: python 根据时间间隔删除文件夹内修