非聚集索引和聚集索引
一.非聚集索引(MyISAM的索引方式):
使用B+Tree作為索引結構,葉節點的data域存放的是數據記錄的地址.主鍵索引圖:
輔助索引圖:
?
主鍵索引和輔助索引沒有本質上的區別,data域都保存的是數據行的地址.
?
二.聚集索引(InnoDB的索引方式):
InnoDB的數據文件本身就是索引文件。在InnoDB中,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,因此InnoDB表數據文件本身就是主索引。
主鍵索引圖:
?
輔助索引:
InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵作為data域.
?
ps:
1.如果innodb表沒有主鍵索引,innodb會自動找一個類似于此的唯一非空列,如果找不到,會增加一個隱藏列來做主索引.
2.Innodb中的每張表都會有一個聚集索引,而聚集索引又是以物理磁盤順序來存儲的,自增主鍵會把數據自動向后插入,避免了插入過程中的聚集索引排序問題。
?
其實到這兒,應該能明確一點,無論是MyISAM還是InnoDB,mysql都試圖能建立起一種快速的數據查找方式.mysql利用B+Tree來解決這個問題.MyISAM只有索引文件是B+Tree方式來組織數據,數據文件并不是;所以對于MyISAM只將索引放入內存緩存;InnoDB因為數據文件本就是B+Tree方式組織,所以InnoDB是可以將索引和數據文件都放入內存;這就是為什么key_buffer_size對myisam至關重要;而innodb_buffer_size對innodb至關重要的原因.兩者在解決數據快速訪問的方式上是相同的.
三.覆蓋索引
覆蓋索引指的是數據的讀取不必經過數據行,而是直接從索引中讀取.對mysql,是效率最好的讀取方式.
對于覆蓋索引而言,myisam和innodb有截然不同的表現(非聚集索引和聚集索引)
?
建立表:
CREATE TABLE `test` (`id` int(11) NOT NULL AUTO_INCREMENT,`time` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `time` (`time`) ) ENGINE=MyISAM;
插入數據:
insert into test(time) values(1); insert into test(time) values(2);
我們來查詢一條數據,看看mysql解釋器表現:
mysql> explain select id from test where time=1; +----+-------------+-------+------+---------------+------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+-------+------+-------------+ | 1 | SIMPLE | test | ref | time | time | 5 | const | 1 | Using where | +----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
注意Extra列,沒有出現using index;也就是沒有使用覆蓋索引;這很好理解,因為非聚集索引,該查詢先查詢了time索引(或key cache),找到對應記錄的地址,然后去數據行找數據了;mysql每次查詢只能用到一個索引.
如果是以下語句,就用到了覆蓋索引:
mysql> explain select time from test where time=1; +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+ | 1 | SIMPLE | test | ref | time | time | 5 | const | 1 | Using where; Using index | +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+
用到了time索引,只要求返回time列,不必去數據行找數據;直接從索引中找到數據返回;
?
現在我們將該表轉為innodb,看看innodb的表現:
?
mysql> explain select id from test where time=1; +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+ | 1 | SIMPLE | test | ref | time | time | 5 | const | 1 | Using where; Using index | +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+
用到了覆蓋索引.
mysql> explain select time from test where time=1; +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+ | 1 | SIMPLE | test | ref | time | time | 5 | const | 1 | Using where; Using index | +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+
?
轉載于:https://www.cnblogs.com/itfenqing/p/8053579.html
總結
以上是生活随笔為你收集整理的非聚集索引和聚集索引的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: es6 函数解构的用途
- 下一篇: 学习 git clone 几种不同的协议