索引

lucsa發表於2024-03-21

一、索引概述

索引是幫助 MySQL 高效獲取資料資料結構(有序)。在資料之外,資料庫系統還維護著滿足特定查詢演算法的資料結構,這些資料結構以某種方式引用(指向)資料,這樣就可以在這些資料結構上實現高階查詢演算法,這種資料結構就是索引。

優點:

  • 提高資料檢索效率,降低資料庫的IO成本
  • 透過索引列對資料進行排序,降低資料排序的成本,降低CPU的消耗

缺點:

  • 索引列也是要佔用空間的
  • 索引大大提高了查詢效率,但降低了更新的速度,比如 INSERT、UPDATE、DELETE

二、索引結構

MySQL的索引實在儲存引擎層實現的,不同儲存引擎由不同的結構,主要包含一下幾種:

索引結構描述
B+Tree 最常見的索引型別,大部分引擎都支援B+樹索引
Hash 底層資料結構是用雜湊表實現,只有精確匹配索引列的查詢才有效,不支援範圍查詢
R-Tree(空間索引) 空間索引是 MyISAM 引擎的一個特殊索引型別,主要用於地理空間資料型別,通常使用較少
Full-Text(全文索引) 是一種透過建立倒排索引,快速匹配文件的方式,類似於 Lucene, Solr, ES

索引InnoDBMyISAMMemory
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; 查一下支援哪些儲存引擎。

三、儲存引擎的特點

區別

特點InnoDBMyISAMMemory
儲存限制 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 引擎。

相關文章