mysql索引操作
索引初識
什麼是索引
索引相當於mysql的一種鍵,是儲存引擎能快速找到資料的一種資料結構,具有非常好的效能,尤其當表中資料很多時,索引就顯得尤為重要,索引優化是資料查詢效能優化的最有效的手段,它能將資料查詢速度提公升幾個數量級
既然索引如此優秀,是不是索引越多越好?
答案當然是否定的,索引可以極快的加快查詢速度,但是插入索引是個很佔記憶體的事情,插入過多的索引會使得io操作時間增加,而且插入索引很費時間,總的一點就是索引是典型的以空間換時間,所以我們需要合理的平衡索引的使用
索引原理
磁碟io
我們通過指令訪問資料庫,資料庫會在硬碟中尋找資料,每次讀取資料花費的時間可以分為尋道時間、旋轉延遲、傳輸時間三個部分,磁碟io主要包括尋道時間、旋轉延遲以及傳輸時間。
磁碟讀取資料靠的是機械運動,尋道時間指的是磁臂移動到指定磁軌所需要的時間,主流磁碟一般在5ms以下;
旋轉延遲就是我們經常聽說的磁碟轉速,比如乙個磁碟7200轉,表示每分鐘能轉7200次,也就是說1秒鐘能轉120次,旋轉延遲就是1/120/2 = 4.17ms;
傳輸時間指的是從磁碟讀出或將資料寫入磁碟的時間,一般在零點幾毫秒,相對於前兩個時間可以忽略不計
那麼訪問一次磁碟的時間,即一次磁碟io的時間約等於5+4.17 = 9ms=0.01s,這對於我們人來說是個微不足道的事情,因為我們人眨一次眼睛就需要0.3s,但是對計算機cpu而言這是乙個巨大的時間浪費,因為cpu每秒大概可以處理5億條指令,那麼一次磁碟io時間cpu可以處理5百萬條指令,所以我們需要加快查詢效率,儘量減少磁碟io的次數
磁碟預讀
基於磁碟io原理,我們應該減少磁碟io次數,所以計算機做了優化,即會在每次從磁碟中讀取資料的時候多讀出一些資料來到記憶體中(它認為你馬上就會使用到接下來的資料),這個資料大小是固定的,大概是4kb或者8kb,不同作業系統讀取資料大小不同,linux可在系統中設定讀取資料大小,預設為4kb,也叫乙個block。
索引資料結構
索引的資料結構為b+樹
b(balance),也就是平衡樹,b樹是在二叉樹的基礎之上進行改良得到的,它的作用是保證每一次資料查詢所經歷的io次數一致
b+樹同樣在b樹的基礎上做了一些強化,比如:
保持樹的高度,保證每一次資料查詢所經歷的io次數一致
b+樹不在分支節點儲存資料,只在葉子節點上儲存資料,這樣就可以極大減少樹的高度,一般為2-4層,極大減少io次數
b+樹在相鄰葉子節點上增加了雙向鍊錶,這樣會極大加快範圍型資料的查詢
索引型別
索引分為聚集索引(聚簇索引)和輔助索引(非聚集索引、非聚簇索引)兩種,兩者各有異同
相同的是:不管是聚集索引還是輔助索引,其內部都是b+樹的形式,即高度是平衡的,葉子結點存放著所有的資料。
聚集索引與輔助索引不同的是:葉子結點存放的是否是一整行的資訊
innodb有且只有乙個聚集索引
主鍵會預設自帶聚集索引+非空+唯一
unique預設自帶輔助索引+唯一
索引的建立和刪除
建立create index 索引名 on 表名(欄位名);
create index ind_age on t1(age);
create index 索引名 on 表名(欄位名1,欄位名2,……) ; :建立乙個聯合索引
create index ind_mix on t1(age,name,***) ;
刪除drop index 索引名 on 表名
drop index ind_age on t1;
如何正確使用mysql資料庫
從庫的角度出發
搭建集群
讀寫分離
分庫從表的角度出發
合理的安排表與表之間的關係:該拆就拆,該合就合
盡量把固定長度的字段放在前面
盡量使用char型別而不是varchar型別
從資料角度出發
在where處盡量將篩選範圍縮小到乙個足夠小的範圍:分頁
盡量使用連表查詢而不是子查詢
刪除或修改資料的時候盡量使用主鍵
合理建立和使用索引
合理建立和使用索引
建立索引
選擇區分度比較大的字段作為索引
大概<1/10相似度的即可,性別之類的字段不適合做索引
選擇長度小的字段做索引
使用索引
查詢的字段不是索引字段
範圍查詢時,範圍越大,查詢越慢,範圍越小,查詢越快
資料很多的情況下:where age>10 或者 where age!=1之類查詢比較慢
資料很多的情況下:where age>100000或者where=2的情況就查詢很快
like分為兩種情況
where name like 'a%':這種情況查詢速度很快
where name like '%a':這種情況查詢速度很慢
當對索引字段進行計算或者使用函式的時候查詢比較慢,所以要保持索引的乾淨度
and和or
and : where age and ***這種查詢速度較快,只要查詢欄位中有索引欄位就會命中索引
or :where age and ***這種查詢速度較慢,只要age和***都是索引欄位時才會快
最左字首匹配原則(聯合索引)
對於組合索引mysql會一直向右匹配直到遇到範圍查詢(>、
查詢索引欄位但使用的型別與索引欄位不一致時,查詢會很慢
select 欄位中在包含oreder by 中的字段時查詢速度才快
覆蓋索引
覆蓋索引就是在查詢資料的時候可以直接在輔助索引的葉子節點中得到資料,不需要回表到聚集索引中尋找資料
索引合併(聯合索引)
分別建立的兩個索引可以合併為乙個聯合索引,一般在and和or中使用,如a=1 or b=10時可以建立聯合索引
執行計畫
能夠查詢sql語句有沒有按照預期執行,可以檢視索引使用情況以及type等級
explain sql執行語句
慢查詢優化
0.先執行看看是否真的很慢,注意設定sql_no_cache
1.where條件單錶查,鎖定最小返回記錄表。這句話的意思是把查詢語句的where都應用到表中返回的記錄數最小的表開始查起,單錶每個字段分別查詢,看哪個欄位的區分度最高
2.explain檢視執行計畫,是否與1預期一致(從鎖定記錄較少的表開始查詢)
3.order by limit 形式的sql語句讓排序的表優先查
4.了解業務方使用場景
5.加索引時參照建索引的幾大原則
6.觀察結果,不符合預期繼續從0分析
mysql慢日誌
在mysql中開啟並設定
當有mysql語句的執行時間超過設定的時間時會將這條sql語句記錄下來
這個時候我們就可以檢視mysql慢日誌去實現定期的優化
mysql 雜湊索引 MySQL索引之雜湊索引
雜湊索引 hash index 建立在雜湊表的基礎上,它只對使用了索引中的每一列的精確查詢有用。對於每一行,儲存引擎計算出了被索引的雜湊碼 hash code 它是乙個較小的值,並且有可能和其他行的雜湊碼不同。它把雜湊碼儲存在索引中,並且儲存了乙個指向雜湊表中的每一行的指標。在mysql中,只有me...
mysql主鍵索引 MySQL索引之主鍵索引
在mysql裡,主鍵索引和輔助索引分別是什麼意思,有什麼區別?上次的分享我們介紹了聚集索引和非聚集索引的區別,本次我們繼續介紹主鍵索引和輔助索引的區別。1 主鍵索引 主鍵索引,簡稱主鍵,原文是primary key,由乙個或多個列組成,用於唯一性標識資料表中的某一條記錄。乙個表可以沒有主鍵,但最多只...
mysql聚集索引 MySQL索引之聚集索引介紹
在mysql裡,聚集索引和非聚集索引分別是什麼意思,有什麼區別?在mysql中,innodb引擎表是 聚集 索引組織表 clustered index organize table 而myisam引擎表則是堆組織表 heap organize table 也有人把聚集索引稱為聚簇索引。當然了,聚集索...