一、索引概述
索引是幫助 MySQL 高效獲取資料的資料結構(有序)。在資料之外,資料庫系統還維護著滿足特定查詢演算法的資料結構,這些資料結構以某種方式引用(指向)資料,這樣就可以在這些資料結構上實現高階查詢演算法,這種資料結構就是索引。
優點:
- 提高資料檢索效率,降低資料庫的IO成本
- 透過索引列對資料進行排序,降低資料排序的成本,降低CPU的消耗
缺點:
- 索引列也是要佔用空間的
- 索引大大提高了查詢效率,但降低了更新的速度,比如 INSERT、UPDATE、DELETE
二、索引結構
MySQL的索引實在儲存引擎層實現的,不同儲存引擎由不同的結構,主要包含一下幾種:
索引結構 | 描述 |
---|---|
B+Tree | 最常見的索引型別,大部分引擎都支援B+樹索引 |
Hash | 底層資料結構是用雜湊表實現,只有精確匹配索引列的查詢才有效,不支援範圍查詢 |
R-Tree(空間索引) | 空間索引是 MyISAM 引擎的一個特殊索引型別,主要用於地理空間資料型別,通常使用較少 |
Full-Text(全文索引) | 是一種透過建立倒排索引,快速匹配文件的方式,類似於 Lucene, Solr, ES |
索引 | InnoDB | MyISAM | Memory |
---|---|---|---|
B+Tree索引 | 支援 | 支援 | 支援 |
Hash索引 | 不支援 | 不支援 | 支援 |
R-Tree索引 | 不支援 | 支援 | 不支援 |
Full-text | 5.6版本後支援 | 支援 | 不支援 |
預設儲存引擎是InnoDB。
找個例子看一下:
#查詢account表的建表語句
show create table account;
#查詢結果
CREATE TABLE `account` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`name` varchar(10) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
`money` int DEFAULT NULL COMMENT '餘額',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='賬戶表'
ENGINE=InnoDB 可以看到未指定儲存引擎,預設儲存引擎是InnoDB
如果建立表時候想指定儲存引擎,ENGINE=XXXX就可以了。
可以透過 show engines; 查一下支援哪些儲存引擎。
三、儲存引擎的特點
區別
特點 | InnoDB | MyISAM | Memory |
---|---|---|---|
儲存限制 | 64TB | 有 | 有 |
事務安全 | 支援 | - | - |
鎖機制 | 行鎖 | 表鎖 | 表鎖 |
B+tree索引 | 支援 | 支援 | 支援 |
Hash索引 | - | - | 支援 |
全文索引 | 支援(5.6版本之後) | 支援 | - |
空間使用 | 高 | 低 | N/A |
記憶體使用 | 高 | 低 | 中等 |
批次插入速度 | 低 | 高 | 高 |
支援外來鍵 | 支援 | - | - |
InnoDB
介紹: InnoDB 是一種兼顧高可靠性和高效能的通用儲存引擎,在 MySQL 5.5 之後,InnoDB 是預設的 MySQL 引擎。
特點:
- DML 操作遵循 ACID 模型,支援事務
- 行級鎖,提高併發訪問效能
- 支援外來鍵約束,保證資料的完整性和正確性
檔案: xxx.ibd: xxx代表表名,InnoDB 引擎的每張表都會對應這樣一個表空間檔案,儲存該表的表結構(frm、sdi)、資料和索引。
引數:innodb_file_per_table,決定多張表共享一個表空間還是每張表對應一個表空間
#查詢表變數裡的innodb_file_per_table開關
show variables like 'innodb_file_per_table';
查詢結果是ON,開啟的,開啟就代表每張表對應一個表空間
我們可以開啟mysql的資料存放目錄
cd /var/lib/mysql/資料庫名
看到"表名.ibd"
可以使用MySql8.0自帶的工具ibd2sdi讀取到ibd檔案中的相關資訊
如果mysql是docker安裝的則先進入容器再找到指定檔案:sudo docker exec -it 27e /bin/bash
邏輯儲存結構:
MyISAM
介紹: MyISAM 是 MySQL 早期的預設儲存引擎。
特點:
- 不支援事務,不支援外來鍵
- 支援表鎖,不支援行鎖
- 訪問速度快
檔案:
- xxx.sdi: 儲存表結構資訊(文字檔案,可以直接開啟看)
- xxx.MYD: 儲存資料
- xxx.MYI: 儲存索引
#建立一張表觀察一下試試
CREATE TABLE `myisam_table` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`name` varchar(10) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='測試MyISAM'
#進入docker MySql容器
sudo docker exec -it 27e /bin/bash
#進入bian_test庫資料夾下
cd /var/lib/mysql/bian_test
#可以看到如下三個檔案
myisam_table.MYD myisam_table.MYI myisam_table_685.sdi
Memory
介紹: Memory 引擎的表資料是儲存在記憶體中的,受硬體問題、斷電問題的影響,只能將這些表作為臨時表或快取使用。
特點:
- 存放在記憶體中,速度快
- hash索引(預設)
檔案:
- xxx.sdi: 儲存表結構資訊
#建立一張表觀察一下試試
CREATE TABLE `memory_table` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`name` varchar(10) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
PRIMARY KEY (`id`)
) ENGINE=Memory DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='測試Memory'
#進入docker MySql容器
sudo docker exec -it 27e /bin/bash
#進入bian_test庫資料夾下
cd /var/lib/mysql/bian_test
#可以看到如下檔案
memory_table_686.sdi
四、怎麼選擇儲存引擎
在選擇儲存引擎時,應該根據應用系統的特點選擇合適的儲存引擎。對於複雜的應用系統,還可以根據實際情況選擇多種儲存引擎進行組合。
- InnoDB: 如果應用對事物的完整性有比較高的要求,在併發條件下要求資料的一致性,資料操作除了插入和查詢之外,還包含很多的更新、刪除操作,則 InnoDB 是比較合適的選擇
- MyISAM: 如果應用是以讀操作和插入操作為主,只有很少的更新和刪除操作,並且對事務的完整性、併發性要求不高,那這個儲存引擎是非常合適的。
- Memory: 將所有資料儲存在記憶體中,訪問速度快,通常用於臨時表及快取。Memory 的缺陷是對錶的大小有限制,太大的表無法快取在記憶體中,而且無法保障資料的安全性
電商中的足跡和評論適合使用 MyISAM 引擎,快取適合使用 Memory 引擎。