索引原理mysql
若是一本新華字典假如沒有目錄,想要查找某個字,就不得不從第一頁開始查找,一直找到最後一頁(若是要找的字在最後一頁),這個過程很是耗時,這種場景至關於數據庫中的全表掃描的概念,也就是循環表中的每一條記錄看看該記錄是否知足條件,掃描次數爲表的總記錄數。sql
新華字典中都會有目錄都有查找方法(好比按拼音查找、按部首查找),假如按拼音查找,咱們根據拼音就能瞬速定位到要找的漢字,而這個漢字後面還有這個漢字對應的頁數,咱們直接翻到該頁就能找到,整個查找過程很是快,用時很是短。這個原理就是數據庫中索引的原理。這裏的按拼音查找、按部首查找是兩種不一樣的查找方式,經過每種方式都能快速找到,在數據庫中也有不少查找方式,稱之爲索引方法,有BTREE、HASH兩種方式數據庫
BTREE:一顆倒立的樹,每一個節點都有父節點,父節點下面的節點稱之爲子節點(葉子節點),比父節點值小的位於父節點下面的左方,比父節點值大的子節點放置在父節點下面的右下方。ide
記錄索引列的值和對應的記錄所在的磁盤位置,每次排除掉一半, 檢索一次至關排除掉2的n次冪,使用二叉樹排除30次至關於全表排除10億次。好比查詢id=11的值,首先和6比,比6大就排除掉左邊的,繼續和9比較,11比9大,又排除掉左邊的通常,和11進行比較,相等就找到告終果。當數據量很大的時候,每次都排除掉一半,排除的數據量是很是驚人的。工具
Hash:Hash索引只能等值匹配,想範圍查詢,左前綴查詢都不適用, 其他大部分場景spa
爲何要使用索引?code
索引大大減小了存儲引擎須要掃描的數據量orm
索引能夠幫助咱們進行排序以免使用臨時表blog
索引能夠把隨機IO變爲順序IO排序
索引類型
主鍵索引(primary key):添加了主鍵就有了主鍵索引,能夠在建立表的時候指定主鍵,也能夠在建立成功以後再增長
惟一索引(unique):添加了惟一約束就有了惟一索引,惟一索引能夠有多個null
普通索引(normal):通常是先建表,後面再建立索引,普通索引使用的最多
全文索引(fulltext):主要針對文本段落等,全文索引只能應用MyISAM引擎
空間索引(spatial): 使用較少,而且mysql支持的還很差
關於惟一性有兩種作法:
經過程序來保證數據的惟一性
業務上具備惟一特性的字段,即便是多個字段的組合,也必須建成惟一索引。說明:不要覺得惟一索引影響了 insert 速度,這個速度損耗能夠忽略,但提升查找速度是明顯的;另外即便在應用層作了很是完善的校驗控制,只要沒有惟一索引,根據墨菲定律,必然有髒數據產生。(來自阿里巴巴Java開發手冊)
全文索引只能用於MyISAM引擎,一般若是用到全文索引通常經過Elasticsearch、Solr、Lucene等技術來實現。
索引語法
-- 建立普通索引:
create index 索引名 on 表(列1【ASC|DESC】, 列2 ASC|DESC】)
-- 建立惟一索引
create unique index on 表名(列名)
主鍵索引名爲 pk_字段名,pk即 primary key
惟一索引名爲 uk_字段名; uk即 unique key
普通索引名則爲 idx_字段名;idx即index的簡稱。
③索引字段
一個索引能夠針對一個字段進行建立,也能夠指定多個字段建立複合索引。
④在哪些列上適合添加索引
頻繁做爲查詢條件的列或者鏈接條件的列適合建立索引,即Where中的列或者是鏈接子句指定的列
惟一性太差的字段不適合建立索引,如性別
更新很是頻繁的字段不適合建立索引
不做爲where條件的字段不要建立索引
選用NOT NULL的列
儘可能使用字段長度小的列做爲索引
使用數據類型簡單的列(int 型,固定長度)
ASC | DESC 選項 除非顯式指定降序 (DESC),不然列以升序 (ASC) 排序。無論索引是升序排列仍是降序排列,在執行升序或降序 ORDER BY 操做時都會使用索引。可是若是經過混合的升序和降序屬性來執行 ORDER BY,則僅當索引是用一樣的升序和降序屬性建立的時才使用索引。
-- 能夠顯式指定索引字段的順序,默認爲升續
CREATE INDEX idx_username ON tbl_user(username ASC);
-- 對於較長的字符內容能夠指定前N個字節建立索引,不必爲整個值都建立索引
CREATE INDEX idx_username ON tbl_user(contnet(20) ASC);
-- 複合索引:基於多個字段共同建立索引(區分度最大的字段放在前面,常常會被使用到的列在前面)
CREATE INDEX idx_username_email ON tbl_user(username, email);
-- 刪除索引
DROP INDEX idx_username ON tbl_user;
-- 查看某個表的索引,兩種方式效果同樣
SHOW INDEX FROM tbl_user;
SHOW KEYS FROM tbl_user;
若是是先建表,表中有比較多的數據,此時再建立索引,建立完索引須要等一會,讓索引在後臺建立完再使用
索引數量控制,單張表中索引數量不該超過5個,單個索引中的字段數不超過5個。
索引存儲的位置位於mysql安裝的/xxx/data目錄下, 索引能提升查詢速度,但對update/delete/insert變慢,由於還要從新維護索引文件,通常狀況下查詢次數遠大於增刪改
show index from 表名;
show keys from 表名;
- 刪除重複和冗餘的索引(第三方工具須要額外安裝)
pt-duplicate-key-checker h=127.0.0.1
-- 更新索引統計信息及減小索引碎片
ANALYZE TABLE <table_name>
-- 清理碎片(注意會鎖表)
OPTIMIZE table <table_name>