<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
字首索引
MySQL 字首索引能有效減小索引檔案的大小,提高索引的速度。但是字首索引也有它的壞處:MySQL 不能在 ORDER BY 或 GROUP BY 中使用字首索引,也不能把它們用作覆蓋索引(Covering Index)。
複合索引
集一個索引包含多個列(最左字首匹配原則)
唯一索引
索引列的值必須唯一,但允許有空值
全文索引
在MySQL 5.6版本以前,只有MyISAM儲存引擎支援全文引擎.在5.6版本中,InnoDB加入了對全文索引的支援,但是不支援中文全文索引.在5.7.6版本,MySQL內建了ngram全文解析器,用來支援亞洲語種的分詞.
全文索引為FUllText,在定義索引的列上支援值的全文查詢,允許在這些索引列中插入重複值和空值,全文索引可以在CHAR,VARCHAR,TEXT型別列上建立
主鍵索引
設定主鍵後資料會自動建立索引,InnoDB為聚簇索引
單列索引
即一個索引只包含單個列,一個表可以有多個單列索引
覆蓋索引
覆蓋索引是指一個查詢語句的執行只用從所有就能夠得到,不必從資料表中讀取,覆蓋索引不是索引樹,是一個結果,當一條查詢語句符合覆蓋索引條件時候,MySQL只需要通過索引就可以返回查詢所需要的資料,這樣避免了查到索引後的回表操作,減少了I/O效率
-- 目前有一個key(name)索引,聚簇索引是key(id) -- 使用了覆蓋索引 select id from stu where key = '天天'; -- 不使用覆蓋索引,因為查詢的結果無法從普通索引樹中得到 select * from stu where key = '天天'
檢視索引
show index from table_name;
列名解析:
列名title | 解釋desc | 取值value |
---|---|---|
table | 索引對應表的名稱 | DB中的表 |
Non_unique | 索引包含value是否為唯一(是否為唯一索引) | 0代表是唯一,1代表不是 |
Key_name | 索引的名稱 | 不命名為建立時列名稱,聯合查詢為Seq_in_index為1的列名稱,重複是使用_+number區分 |
Seq_in_index | 索引中列的序列號,從1開始,表明在聯合查詢中的順序,我們可以根據這個推斷出聯合索引中索引的前後順序(使用最左優化原則) | 從1遞增至聯合索引的列數 |
Column_name | 索引的列名 | 索引的列名 |
Collation(n.排序方式,校隊) | 指排序方式 | A表示升序,B表示降序,NULL表示未排序。 |
Cardinality | 基數的意思,表示索引中唯一值的數目的估計值,我們知道某個欄位的重複值越少越適合建立索引,所以我們一般根據Cardinality來判斷索引是否具有高選擇性,如果這個值非常小,就需要評估這個欄位是否適合做索引 | 最小值為1,表示索引的列欄位值都重複,最大為表中欄位數 |
Sub_part | 當索引是字首索引的時候,sub_part表示字首的字元數 | 非字首為0,字首索引為字元數 |
Packed | 指示關鍵字如何被壓縮。 | 如果沒有被壓縮,則為NULL |
NUll | 如果列含有null,則含有yes | null/yes |
Index_type | 表示索引型別,全文索引是Fulltext,Memory引擎對應Hash,其他大多數是Btree,Rtree沒有見過 | FULLTEXT,HASH,BTREE,RTREE |
Comment | 註釋 | ... |
Index_comment | 註釋 | ... |
刪除索引
drop index index_name on table name; -- 錯誤刪除primary索引 drop index `PriMary` on temp; -- >:Incorrect table definition; there can be only one auto column and it must be defined as a key
主鍵索引
-- mysql中InnoDB使用主鍵索引作為聚簇索引,主鍵索引無法使用 -- 建立時候,主鍵自動定義 create table temppp(id int auto_increment,primary key(id),name varchar(20) not null unique); -- 無法刪除primary key索引,需要改變的時候,首先需要刪除主鍵列,刪除後自動選擇一行unique的列作為主鍵索引 alter table temppp drop COLUMN id;
檢視:
刪除前:
刪除後:
單列索引
普通的索引,沒有什麼介紹
-- 建表時候表級約束建立索引 create table otest( id int(25) PRIMARY key, `name` varchar(255), -- 這一句就是在建立普通欄位的索引,但是無法設定名字 key(`name`) ) -- 建表後 alter table otest add index key(`name`);
檢視:(注意和字首索引Sub_part的區別)
唯一索引
當索引的列是unique的時候,會生成唯一索引,唯一索引關於null有下列兩種情況
SQLSERVER 下的唯一索引的列,允許null值,但最多允許有一個空值
-- sql server 下實驗程式碼 create table temp ( id int primary key, age varchar(20) unique, ); create unique index age on temp(age) execute sp_helpindex @objname='temp'
檢視:
-- 插入兩條null語句 insert into temp values(1,null); insert into temp values(2,null);
結果:
MYSQL下的唯一索引的列,允許null值,並且允許多個空值
-- mysql下實驗程式碼 create table otest ( id int primary key, age varchar(20) unique, key(age) ); show index from otest
檢視:
會建立兩個索引,一個非聚簇索引,一個是唯一索引
-- 插入兩條null語句 ....與上程式碼相似
結果:
可以插入兩個空值(明人不說暗話,我喜歡MySQL)
字首索引
ALTER TABLE table_name ADD KEY(column_name(prefix_length)); -- 表級建立 create table temppp (id int auto_increment,primary key(id), name varchar(20) not null unique, key(name(2))); -- 表級建立 alter table temppp add index(name(2))
檢視:
字首索引範例的博文:https://www.jb51.net/article/243195.htm很好,推薦
複合索引
-- 建表時候表級約束建立索引 drop table if exists `otest`; create table otest( id int(25) PRIMARY key, `name` varchar(255), age varchar(255), -- 這一句就是在建立普通欄位的索引,但是無法設定名字 key(`name`,age) ); -- 建表後 alter table otest add key(`name`,age);
檢視:
複合索引的最左字首匹配原則:
對於複合索引,查詢在一定條件才會使用該索引
-- 假設一個下列的索引 alter table otest add index(id,name,age); -- 只有查詢條件滿足組合索引的字首匹配才能使用索引,也就是對於查詢的順序為 -- id id,name id,name,age這三種情況下才能使用組合索引 -- 對於下列這種就無法使用索引 select * from otest where id=?,age=? -- 缺少了name列 select * from otest where name=?,age=? -- 缺少了id列 -- 對於下列查詢MySQL會使用優化調整位置 select * from otest where id=?,age=?,name=? -- 查詢順序是 id,age,name看起來是不能使用索引的,但是MySQL在執行的時候會進行優化,將順序調整為id name age。
複合索引的優點
減少開銷。建一個聯合索引(col1,col2,col3),實際相當於建了(col1),(col1,col2),(col1,col2,col3)三個索引。每多一個索引,都會增加寫操作的開銷和磁碟空間的開銷。對於大量資料的表,使用聯合索引會大大的減少開銷!
覆蓋索引。對聯合索引(col1,col2,col3),如果有如下的sql: select col1,col2,col3 from test where col1=1 and col2=2。那麼MySQL可以直接通過遍歷索引取得資料,而無需回表,這減少了很多的隨機io操作。減少io操作,特別的隨機io其實是dba主要的優化策略。所以,在真正的實際應用中,覆蓋索引是主要的提升效能的優化手段之一。
效率高。索引列越多,通過索引篩選出的資料越少。有1000W條資料的表,有如下sql:select from table where col1=1 and col2=2 and col3=3,假設假設每個條件可以篩選出10%的資料,如果只有單值索引,那麼通過該索引能篩選出1000W10%=100w條資料,然後再回表從100w條資料中找到符合col2=2 and col3= 3的資料,然後再排序,再分頁;如果是聯合索引,通過索引篩選出1000w10% 10% *10%=1w。
全文索引(FULLTEXT)
在模糊搜尋中很有效,搜尋全文中的某一個欄位,可以參考這篇博文:https://www.jb51.net/article/243201.htm
我們先進行下面一個實驗看看InnoDB下的主鍵索引的一個現象。
create table otest( id int(25) PRIMARY key, `name` varchar(255), age varchar(255) ); insert into otest values(3,'q',1); insert into otest values(1,'q',1); insert into otest values(5,'q',1); insert into otest values(2,'q',1); insert into otest values(6,'q',1) -- 檢視現象 SELECT * from otest
檢視:
我們插入進去的時候,資料的id都是亂序的,為什麼這裡最後select查詢出來的結果都是進行了排序?
這是因為InnoDB索引底層實現的是B+tree,B+tree具有下列的特點:
和B-tree一樣是自平衡樹
m個子樹上層有m箇中間節點,但是m箇中間節點只儲存索引,而不儲存資料。
所有的葉子結點中包含了全部關鍵字的資訊,及指向含有這些關鍵字記錄的指標,且葉子結點本身依關鍵字的大小自小而大的順序連結。
所有的非終端結點可以看成是索引部分,結點中僅含有其子樹根結點中最大(或最小)關鍵字。
所以上面的排序是為了使用B+tree的結構,B+tree為了範圍搜尋,將主鍵按照從小到大排序後,拆分成節點。後續還有新的節點進入的時候,和B-tree相同的操作,會進行分裂。
一般來說,聚簇索引的B+tree都是三層
B-tree是所有結點都要儲存資料,相同的資料更深,查詢速度變慢,所以底層沒有使用B-tree。
MySQL的InnoDB儲存引擎設計時頂層頁目錄常駐記憶體,對於2-4層B+樹查詢時,聚簇索引IO查詢1-3次,也就是和硬碟互動進行IO讀
計算一個元素的位元組大小:**欄位型別所佔位元組 + 一個指標的位元組數(32位元4byte,64位元8byte)
實際單表列過多要拆表,這樣主表存資料更多深度也低,查詢也快
對於InnoDB來說主鍵索引就是聚簇索引,而普通索引就是非聚簇索引
對於表中資料操作過多會造成存在許多的頁碎片,關於碎片整理可以看我這篇博文
https://www.jb51.net/article/243206.htm
InnoDB中主鍵索引一定是聚簇索引,聚簇索引一定是主鍵索引。
為什麼這裡輔助索引葉子結點不直接儲存資料呢?
MYISAM只有非聚簇索引,索引最終指向的都是實體地址。
Q:既然有回表的存在,那麼聚簇索引的優勢在哪裡?
Q:主鍵索引作為聚簇索引需要注意什麼
查詢語句中使用Like關鍵字
在查詢語句中使用LIke關鍵字進行查詢時,如果匹配字串的第一個字元為"%",索引不會使用。如果“%”不是在第一位,索引就會使用
查詢語句中使用多列索引
多列索引是在表的多個欄位上建立的索引,滿足最左字首匹配原則,索引才會被使用
查詢語句中使用OR關鍵字
查詢語句只有Or關鍵字時候,如果OR前後的兩個條件都是索引,這這次查詢將會使用索引,否則Or前後有一個條件的列不是索引,那麼查詢中將不使用索引
5.關於Explain語句
作者不會,建議查詢,這裡列出是作為提醒
永遠年輕,永遠熱淚盈眶
TIPS:MySQL底層儲存檔案:
MyISAM:.frm是存放表結構的檔案,.MYD是存放表資料的檔案,.MYI是存放表索引的檔案
InnoDB:.frm存放表結構,.Ibd是存放表資料和索引的
到此這篇關於MySQL索引機制的詳細解析及原理的文章就介紹到這了,更多相關MySQL索引機制內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45