MySql中索引的新增刪除語句程式碼實現,原則和資料結構
什麼是索引
在現實生活中,我們經常去圖書館查閱圖書。
現在我們將所有圖書雜亂無章的擺放在一起,那麼找一本書就像大海撈針一樣效率非常低。
如果我們按分類整理排序後,根據類別去找對應的圖書那麼效率就很高了。其實這個過程就是在建立索
引。
檢視mysql中語句執行效率
show variables like '%query%' ;
查詢當前的慢日誌狀態 其中long_query_time表示執行時間比較。
長的記錄 slow_query_log=off 表示慢日誌為關閉狀態。
slow_query_log_file 表示慢日誌儲存的位置。
-- 開啟 慢日誌查詢 set global slow_query_log =1; -- 設定需要記錄的比較慢的sql時間 set long_query_time = 1;
select * from temp_table where id like '%91b4a3ac2edb6f9064d18a8fb286edf9';
超過了一秒的語句可以去相應的目錄下看log檔案
query_time:查詢時間
lock_time:鎖時間
rows_sent:返回條數
rows_examined:掃描行數
索引的優勢與劣勢
優勢
① 類似大學圖書館建書目索引,提高資料檢索的效率,降低資料庫的 IO 成本。
② 通過索引列對資料
進行排序,降低資料排序的成本,降低 CPU 的消耗。
劣勢
① 實際上索引也是一張表,該表儲存了主鍵與索引欄位,並指向實體表的記錄,所以索引列也是要佔用
空間的
② 雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對錶進行INSERT、UPDATE和
DELETE操作 , MySQL不僅要儲存資料,還要更新一下索引檔案 , 理論上來說 , 頻繁的更新索引欄位的數
據 , 表的更新效率會下降
- 普通索引:僅加速查詢
- 唯一索引:加速查詢 + 列值唯一(可以有null) 唯一約束
- 主鍵索引:加速查詢 + 列值唯一(不可以有null)+ 表中只有一個 , 主鍵約束
- 組合(聯合)索引:多列值組成一個索引,注意:最左匹配原則(一會演示)
- 全文索引:瞭解(es)
- hash索引:瞭解(key-value 查詢速度非常高效)
-- 建立普通索引 create index 索引名 on 表名(列名); -- 建立唯一索引 create unique index 索引名 on 表名(列名); -- 建立普通組合索引 create index 索引名 on 表名(列名1,列名2....); -- 建立唯一組合索引 create unique index 索引名 on 表名(列名1,列名2...);
② 修改表時指定
-- 新增一個主鍵,這意味著索引值必須是唯一的,且不能為NULL alter table 表名 add primary key(id); -- 新增唯一索引(除了NULL外,NULL可能會出現多次) alter table 表名 add unique(列名); -- 索引名就是列名 -- 新增普通索引,索引值可以出現多次。 alter table 表名 add index(列名);-- 索引名就是列名
③ 建立表時指定
create table xxx( id int, username varchar(32), age int, primary key(id), -- 主鍵 unique(username), -- 唯一 index(age) -- 普通 );
--刪除索引
-- 直接刪除 drop index 索引名 on 表名; -- 修改表時刪除 alter table 表名 drop index 索引名;
索引建立原則
1. 欄位內資料的辨識度不能低於70%
欄位內資料唯一值的個數不能低於70%,例如:一個表資料只有50行,那麼性別和年齡哪個欄位適
合建立索引,明顯是年齡,因為年齡的唯一值個數比較多,性別只有兩個選項
2. 在經常需要 搜尋 的列上建索引,這樣會大大加快查詢速度,經常使用 where 查詢欄位。
3. 在經常需要 連線 的列上建索引,可以加快連線的速度,經常使用 多表連線欄位(主外來鍵) 內連線 | 外連線。
4. 在經常需要 排序 的列上建索引,因為索引已經是排過序的,這樣一來可以利用索引的排序,加快排序查詢速度,經常使用 group by having | order by 欄位。
* 注意:
那是不是在資料庫表字段中儘量多建索引呢?肯定是不是的。因為索引的建立和維護都是需要耗時的
建立表時需要通過資料庫去維護索引,新增記錄、更新、修改時,也需要更新索引,會間接影響資料庫的
效率。
-- 1.使用like模糊匹配,%萬用字元在最左側使用時 select * from user where username like '%jack88';
-- 2.儘量避免使用or,如果條件有一個沒有索引,那麼會進行全表掃描 select * from user where id = 1 or sex ='male';
-- 3.在索引列上進行計算 select * from user where id + 1 = 2;
-- 4.使用 !=、 not in、is not null時 select * from user where sex != 'male'; select * from user where id not in( 1, 3 ,5);
我們知道索引是幫助MySQL高效獲取排好序的資料結構。
索引= 排序後的資料結構
為什麼使用索引後查詢效率提高很多呢?接下來我們來了解下。
在沒有索引的情況下我們執行一條sql語句,那麼是表進行全域性遍歷,磁碟定址(注意邏輯上相鄰的記錄在磁碟上也並不是一定物理相鄰的)
為了加快的查詢效率,可以維護一個右邊所示的二叉查詢樹,每個節點分別包含索引鍵值和一個指向對
應資料記錄實體地址的指標,這樣就可以運用二叉查詢快速獲取到相應資料。
1. 二叉樹 左邊子節點比父節點小,右邊子節點比父節點大 2. 紅黑樹(平衡二叉樹) 左旋和右旋實現自平衡 3. Hash 雜湊 1. JDK1.7 (陣列+連結串列) 2. JDK1.8 (陣列+紅黑樹) 如果連結串列長度《=8 4. B-Tree (多路搜尋平衡樹) 5. B+Tree【MySQL使用】
資料庫儲存引擎
CREATE TABLE myisam_tab( id INT, username VARCHAR(32) )ENGINE = MYISAM;
使用這個儲存引擎,每個MyISAM在磁碟上儲存成三個檔案。
(1)frm檔案:儲存表的定義資料
(2)MYD檔案:存放表具體記錄的資料
(3)MYI檔案:儲存索引
frm和MYI可以存放在不同的目錄下。MYI檔案用來儲存索引,但僅儲存記錄所在頁的指標,索引的結構是B+樹結構。下面這張圖就是MYI檔案儲存的機制:
MySQL5.5版本之後預設的儲存引擎,支援事務,有自動增長,支援外來鍵約束,支援緩衝區
CREATE TABLE innodb_tab( id INT, username VARCHAR(32) )ENGINE = INNODB;
InnoDB的儲存表和索引也有下面兩種形式:
(1)使用共享表空間儲存:所有的表和索引存放在同一個表空間中。
(2)使用多表空間儲存:表結構放在frm檔案,資料和索引放在IBD檔案中。分割槽表的話,每個分割槽對應單獨的IBD檔案,分割槽表的定義可以檢視我的其他文章。使用分割槽表的好處在於提升查詢效率。
對於InnoDB來說,最大的特點在於支援事務。但是這是以損失效率來換取的。