Mysql索引優化(一)_索引類型

索引對於良好的性能非常關鍵,尤其是在數據量越來越大的時候。恰當的索引對性能的幫助是非常巨大的,不恰當的索引不禁不能對性提升有幫助,當數據量達到一定級別的時候還可能造成性能的下降。所以瞭解索引對Mysql性能優化有着至關重要的作用。

Mysql索引基本類型有 B-Tree,哈希索引,全文索引,空間數據索引(R-Tree)。其中B-Tree哈希全文索引是我們經常用到的。

B-Tree索引

B-Tree索引是我們口中經常說的索引類型(有些存儲引擎中使用的是B+Tree。如InnoDB)。每個引擎對於BTREE索引使用方式是不一樣的。

  • MyISAM引擎使用的是前置壓縮技術,這樣索引會變的很小。而InnoDB則是按照原有的數據格式來存儲的。
  • MyISAM索引是通過數據的物理位置來找到被索引的行,而InnoDB則是根據被索引的行的主鍵來找到被索引行的。

B-Tree索引的所有值都是按順序存儲的,並且每個葉子節點到根節點的距離是相同的。下面給出一個簡單的示意圖

圖片描述

假設有下表:

CREATE TABLE student(
    first_name varchar(20) not null,
    last_name varchar(20) not null,
    age tinyint(3) not null,
    created_at timestamp not null,
    key(first_name ,last_name)
);

可以使用到B-Tree索引的查詢

  • 全值匹配 全值匹配指對索引中的所有列進行匹配。如查詢姓名是 zhang san的人 select * from student where first_name='zhang' and last_name='san'; 這裏使用了索引的第一列與第二列
  • 匹配最左前綴,如查詢姓爲的人 select * from student where first_name='zhang' ;這裏使用了索引的第一列
  • 匹配列前綴,也可以值匹配某一列的開頭部分,如 select * from student where first_name='zha' ;這裏使用了索引的第一列
  • 匹配範圍值,如 select * from student where first_name>'bao' and first_name<'zhang';這樣也會使用到索引的第一列
  • 只訪問索引的查詢,如果查詢條件是 select first_name,last_name from student where first_name='zhang' ;那麼查詢就只會訪問索引,而不會再去根據主鍵回表查詢數據。
這裏需要注意的是;B-Tree 索引需要根據最左前綴查詢,如果不是按照索引的最左列開始查詢,那麼是不會使用到索引的。例如:
select * from student where last_name='san';
select * from student where first_name like '%ha%';
這樣的sql是沒辦法命中索引的。對於第二條sql如果需要使用索引,那麼應該改爲 select * from student where first_name like 'ha%';
哈希索引

哈希索引是基於哈希表實現的,只有精確匹配索引所有列的查詢纔會使用到索引,只有Memory引擎才支持哈希索引。
假設有下表:

CREATE TABLE student(
    first_name varchar(20) not null,
    last_name varchar(20) not null,
    age tinyint(3) not null,
    created_at timestamp not null,
    key using hash(first_name)
) engine=memory;

如果我們要執行select last_name from student where first_name='zhang';,Mysql會先計算zhang的哈希值,然後用該值尋找對應的記錄指針,最後再去比較first_name是否等於zhang
因爲哈希索引只存儲對於的哈希值和行指針,所以哈希索引的結構很緊湊,查詢速度非常快。但是也有一些缺點。

  • 因爲哈希索引只有哈希值與指針,所以每次查詢必須回表去讀取數據行。
  • 因爲哈希索引不是按照索引值順序存儲的,所以哈希索引也不能用於排序。
  • 哈希索引不支持部分索引列查詢,比如 將student表是索引 改爲 hash(first_name,last_name),那麼查詢必須用到first_name,last_name纔會使用到索引。
  • 哈希索引只支持等值比較,所以<,>等範圍查詢是不會使用到索引的。
  • 哈希索引也會存在哈希衝突,當出現衝突的時候,查詢效率就很降低很多。

圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章