日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

非聚集索引和聚集索引

發布時間:2025/4/5 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 非聚集索引和聚集索引 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一.非聚集索引(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

總結

以上是生活随笔為你收集整理的非聚集索引和聚集索引的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。