MySQL的服務器,本質是在內存中的,那么所有對數據的CURD操作,全都是在對內存進行操作。
而,提高數據的CURD操作的效率,有兩種方式:1、組織數據的格式(數據結構);2、算法。
而,數據結構,就是索引,即組織數據的格式。
1、沒有索引的問題
索引:提高數據庫的性能,索引是物美價廉的東西了。不用加內存,不用改程序,不用調sql,只要執行正確的 create index,查詢速度就可能提高成百上千倍。
即:索引的存在,提高了數據的查詢效率,但是降低了數據的插入刪除效率。
但是對于數據來說,大部分時間還是在于讀操作。
1.1、常見索引
主鍵索引 | primary key |
唯一索引 | unique |
普通索引 | index |
全文索引 | fulltext |
因此,之前在表中創建“鍵”,其實就是在創建一個索引。
2、認識磁盤
MySQL 給用戶提供存儲服務,而存儲的都是數據,數據在磁盤這個外設當中。
由馮諾依曼體系結構可知,磁盤的IO效率是很慢的。
因此,如何提高效率,是MySQL的一個重要話題。
再看看磁盤中的一個盤片:
如今,一個扇區的大小已經提升到4KB了,即4096字節。
并且如今,OS和磁盤的交互大小,就是以4KB為交互單位了。
我們在使用Linux,所看到的大部分目錄或者文件,其實就是保存在硬盤當中的。
因此,最基本的,找到一個文件的全部,本質,就是在磁盤找到所有保存文件的扇區。
而對于定位扇區,是有CSH定址法的:
2.1、磁盤隨機訪問
本次IO所給出的扇區地址和上次IO給出扇區地址不連續,這樣的話磁頭在兩次IO操作之間需要作比較大的移動動作才能重新開始讀/寫數據。
2.2、磁盤連續訪問
如果當次IO給出的扇區地址與上次IO結束的扇區地址是連續的,那磁頭就能很快的開始這次 IO操作,這樣的多個IO操作稱為連續訪問。
因此盡管相鄰的兩次IO操作在同一時刻發出,但如果它們的請求的扇區地址相差很大的話也只能稱為隨 機訪問,而非連續訪問。 磁盤是通過機械運動進行尋址的,隨機訪問不需要過多的定位,故效率比較高。
3、MySQL與磁盤交互單位--Page
而MySQL作為一款應用軟件,可以想象成一種特殊的文件系統。
它有著更高的IO場景,所以,為了提高基本的IO效率, MySQL 進行IO的基本單位是16KB。(InnoDB,之后均已InnoDB舉例了。)
mysql> SHOW GLOBAL STATUS LIKE 'innodb_page_size';+------------------+-------+| Variable_name | Value |+------------------+-------+| Innodb_page_size | 16384 | ---- 16384 = 16 * 1024+------------------+-------+1 row in set (0.01 sec)
也就是說,磁盤的基本單位是4KB,而MySQL InnoDB引擎采用16KB進行IO交互。
這個16KB,在MySQL這里,成為Page。
4、建立共識
MySQL中的數據文件,是以Page為單位,保存在磁盤當中的。 |
MySQL的CURD操作,都需要計算得到對應的數據位置。 |
只要涉及計算操作,就要CPU參與,而為了便于CPU參與計算,一定要率先將數據移動到內存中。 |
所以,在特定的時間內,內存和磁盤中都是有數據的。 后續數據操作完畢后,以某種刷新策略,將數據從內存刷新到磁盤中去。 此時就涉及到內存和磁盤的IO了,此時的IO單位就是Page。 |
MySQL為了更好的執行上述操作,MySQL服務器在內存中運行的時候,就在服務器內部,申請了一塊被成為“Buffer Pool”的大塊內存空間,來進行各種緩存。 |
由馮諾依曼體系可以知道,想要提高效率,必須要減少系統和磁盤的IO次數。 |
5、初步理解索引
5.1、建立測試表
必須要添加主鍵,才會默認生成主鍵索引。
create table if not exists user ( id int primary key, --一定要添加主鍵哦,只有這樣才會默認生成主鍵索引age int not null,name varchar(16) not null
);
查看建表信息,默認采用的是InnoDB存儲引擎。(也是我們配置過的)
mysql> show create table user \G*************************** 1. row ***************************Table: userCreate Table: CREATE TABLE `user` (`id` int(11) NOT NULL,`age` int(11) NOT NULL,`name` varchar(16) NOT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=