索引是什么粪薛?有哪些優(yōu)缺點谴返?
答:
索引是一種能幫助MySQL提高查詢效率的數(shù)據結構。
優(yōu)點:
1)快速訪問數(shù)據表中的特定信息中贝,調高檢索速度
2)創(chuàng)建唯一性索引,保證數(shù)據表中每一行數(shù)據的唯一性
3)加速表與表之間的連接
4)使用分組和排序進行數(shù)據檢索時臼朗,可以顯著減少查詢中分組和排序的時間
缺點:
1)雖然提高了查詢速度邻寿,但是降低了更新表的速度,比如update视哑、insert绣否,在更新數(shù)據時,MySQL不僅要更新數(shù)據挡毅,還要更新索引文件
2)建立索引會占用磁盤文件的索引文件使用索引的注意事項蒜撮?
答:
1)使用短索引,短索引不僅可以提高查詢速度跪呈,更能節(jié)省磁盤空間和I/O操作
2)索引列排序段磨,MySQL查詢只使用一個索引,因此如果where子句已經使用了索引的話耗绿,那么order by中的列是不會使用索引的苹支,因此數(shù)據庫默認排序可以符合要求的情況下,不要使用排序操作
3)一般情況下不使用like語句操作误阻,如果非使用不可债蜜,注意like"%aaa%"不會使用索引;而like"aaa%"會使用索引
4)不要在列上進行運算
5)盡量不要使用not和<>操作為什么MySQL官方建議使用自增主鍵作為表的主鍵究反?
答:
因為自增主鍵是連續(xù)的寻定,在插入勾·過程中盡量減少頁分裂,即使要進行頁分裂奴紧,也只會分裂很少一部分特姐,并且自增主鍵都是插入到最后晶丘,所以自增主鍵作為表的主鍵黍氮,對于表的操作來說性能是最高的自增主鍵有哪些優(yōu)缺點唐含?
答:
優(yōu)點:
1)數(shù)據存儲空間小
2)性能最好
3)減少頁分裂
缺點:
1)數(shù)據量過大,可能會超出自增長取值范圍
2)無法滿足分布式存儲沫浆,分庫分表的情況下無法合并表
3)主鍵有自增規(guī)律捷枯,容易被破解
所以是否需要使用自增主鍵,需要根據自己的業(yè)務場景來設計专执。如果是單庫單表淮捆,則優(yōu)先考慮自增主鍵索引有幾種類型?分別如何創(chuàng)建本股?
答:
MySQL 的索引有兩種分類方式:邏輯分類和物理分類攀痊。
按照邏輯分類,索引可分為:
1)主鍵索引:一張表只能有一個主鍵索引拄显,不允許重復苟径、不允許為 NULL;
2)唯一索引:數(shù)據列不允許重復躬审,允許為 NULL 值棘街,一張表可有多個唯一索引,但是一個唯一索引只能包含一列承边,比如身份證號碼遭殉、卡號等都可以作為唯一索引;
3)普通索引:一張表可以創(chuàng)建多個普通索引博助,一個普通索引可以包含多個字段险污,允許數(shù)據重復,允許 NULL 值插入富岳;
4)全文索引:讓搜索關鍵詞更高效的一種索引
按照物理分類罗心,索引可分為:
1)聚集索引:一般是表中的主鍵索引,如果表中沒有顯示指定主鍵城瞎,則會選擇表中的第一個不允許為 NULL 的唯一索引渤闷,如果還是沒有的話,就采用 Innodb 存儲引擎為每行數(shù)據內置的 6 字節(jié) ROWID 作為聚集索引脖镀。每張表只有一個聚集索引飒箭,因為聚集索引的鍵值的邏輯順序決定了表中相應行的物理順序。聚集索引在精確查找和范圍查找方面有良好的性能表現(xiàn)(相比于普通索引和全表掃描)蜒灰,聚集索引就顯得彌足珍貴弦蹂,聚集索引選擇還是要慎重的(一般不會讓沒有語義的自增 id 充當聚集索引);
2)非聚集索引:該索引中索引的邏輯順序與磁盤上行的物理存儲順序不同(非主鍵的那一列)强窖,一個表中可以擁有多個非聚集索引主索引和唯一索引有什么區(qū)別凸椿?
答:
1)主索引不能重復且不能為空,唯一索引不能重復翅溺,但可以為空
2)一張表只能有一個主索引脑漫,但可以有多個唯一索引
3)主索引的查詢性能要高于唯一索引在InnoDB中主鍵索引為什么比普通索引的查詢性能高髓抑?
答:
因為普通索引的查詢會多執(zhí)行一次檢索操作。比如主鍵查詢
select *
from t
where id =10;
只需要搜索id的這棵B+樹优幸,而普通索引查詢
select *
from t
where f = 3;
會先查詢f索引樹吨拍,得到id之后再去搜索id的B+樹,因此多進行了一次檢索网杆,所以執(zhí)行效率就比主鍵索引要低
什么叫回表查詢
答:
普通索引查詢到主鍵后羹饰,回到主鍵索引樹搜索的過程,成為回表查詢碳却。同問題7MySQL中最多可以創(chuàng)建多少索引列队秩?如何查詢一張表的所有索引?
答:
MySQL中最多可以創(chuàng)建16個索引列
查詢表T所有索引:
SHOW INDEX FROM T;
-
MySQL中聯(lián)合索引是什么昼浦?作用是刹碾?
答:
聯(lián)合索引又叫符合索引,MySQL中的聯(lián)合索引座柱,遵循最左匹配原則迷帜,比如,聯(lián)合索引為key(a,b,c)色洞,則能觸發(fā)索引的搜索組合是a , ab , abc這三種查詢
作用如下:
1)用于多字段查詢戏锹,比如,建了一個 key(a,b,c) 的聯(lián)合索引火诸,那么實際等于建了 key(a)锦针、key(a,b)、key(a,b,c) 等三個索引置蜀,對大數(shù)據量的表來說奈搜,這可以減少一部分不必要的開銷;
2)覆蓋索引盯荤,比如馋吗,對于聯(lián)合索引 key(a,b,c) 來說,如果使用
select a,b,c from table where a=1 and b = 1
就可以直接通過遍歷索引取得數(shù)據秋秤,而無需回表查詢宏粤,這就減少了隨機的 IO 操作,減少隨機的 IO 操作灼卢,可以有效的提升數(shù)據庫查詢的性能绍哎,是非常重要的數(shù)據庫優(yōu)化手段之一;
3)索引列越多鞋真,通過索引篩選出的數(shù)據越少
什么是最左匹配原則崇堰?它的生效原則有哪些?
答:
最左匹配原則是MySQL中的一個重要原則,說的是索引以最左邊的為起點任何連續(xù)的索引都能匹配上海诲,當遇到范圍查詢(<繁莹、<、between饿肺、like)就會停止匹配。比如表中有一個聯(lián)合索引字段index(a,b,c):
where a = 1只使用了索引a盾似;
where a = 1 and b = 2只使用了索引a,b;
where a = 1 and b = 2 and c = 3使用了索引a,b,c;
where b = 1 or where c = 1不使用索引;
where a = 1 and c = 3只使用了索引a;
where a = 3 and b like 'xx%' and c = 3只使用了索引a,b;列值為NULL時敬辣,查詢會使用到索引嗎?
答:
在 MySQL 5.6以上的InnoDB存儲引擎會正常觸發(fā)索引零院。但為了兼容低版本的MySQL和兼容其他數(shù)據庫存儲引擎溉跃,不建議使用NULL值來存儲和查詢數(shù)據,建議設置列為NOT NULL告抄,并設置一個默認值索引的常見存儲算法有哪些撰茎?
答:
1)哈希存儲法:以 key、value 方式存儲打洼,把值存入數(shù)組中使用哈希值確認數(shù)據的位置龄糊,如果發(fā)生哈希沖突,使用鏈表存儲數(shù)據募疮;
2)有序數(shù)組存儲法:按順序存儲炫惩,優(yōu)點是可以使用二分法快速找到數(shù)據,缺點是更新效率阿浓,適合靜態(tài)數(shù)據存儲他嚷;
3)搜索樹:以樹的方式進行存儲,查詢性能好芭毙,更新速度快唯一索引和普通索引哪個性能更好筋蓖?
答:
對于查詢操作來說:普通索引和唯一索引的性能接近,都從索引樹中進行查詢
對于更新操作來說:唯一索引要比普通索引執(zhí)行的慢退敦,因為唯一索引需要先將數(shù)據讀取到內存中粘咖,再在內存中進行數(shù)據的唯一校驗,所以執(zhí)行起來要比普通索引慢InnoDB為什么要使用B+樹侈百,而不是B樹涂炎、Hash、紅黑樹或二叉樹设哗?
答:
因為B樹唱捣、Hash、紅黑樹或二叉樹存在以下問題:
1)B樹:不管葉子節(jié)點還是非葉子節(jié)點网梢,都會保存數(shù)據震缭,這樣導致在非葉子節(jié)點中能保存的指針數(shù)量變少(有些資料也稱為扇出),指針少的情況下要保存大量數(shù)據战虏,只能增加樹的高度拣宰,導致IO操作變多党涕,查詢性能變低;
2)Hash:雖然可以快速定位巡社,但是沒有順序膛堤,IO復雜度高;
3)二叉樹:樹的高度不均勻晌该,不能自平衡肥荔,查找效率跟數(shù)據有關(樹的高度),并且IO代價高朝群;
4)紅黑樹:樹的高度隨著數(shù)據量增加而增加燕耿,IO代價高。優(yōu)化器選擇查詢索引的影響因素有哪些姜胖?
答:
優(yōu)化器的目的是使用最小的代價選擇最優(yōu)的執(zhí)行方案誉帅,影響優(yōu)化器選擇索引的因素如下:
1)掃描行數(shù):掃描的行數(shù)越小,執(zhí)行代價就越少右莱,執(zhí)行效率就越高
2)是否使用了臨時表
3)是否排序如何優(yōu)化身份證的索引蚜锨?
答:
在中國因為身份證前6位代表的是地區(qū),所以很多人前6位都是相同的慢蜓,如果我們使用前綴索引為6位的話踏志,性能提升也不是很明顯,但如果設置的位數(shù)過長胀瞪,那么占用的磁盤空間就越大针余,數(shù)據頁能放下的索引值就越少,搜索效率也就越低凄诞。所以優(yōu)化方案有以下兩種:
1)使用身份證倒序存儲圆雁,這樣設置前六位的意義就很大了
2)使用hash值,新創(chuàng)建一個字段用于存儲身份證的hash值