索引對於良好的性能很是關鍵,尤爲是在數據量愈來愈大的時候。恰當的索引對性能的幫助是很是巨大的,不恰當的索引不由不能對性提高有幫助,當數據量達到必定級別的時候還可能形成性能的降低。因此瞭解索引對
Mysql
性能優化有着相當重要的做用。
Mysql索引基本類型有 B-Tree
,哈希索引
,全文索引
,空間數據索引(R-Tree)
。其中B-Tree
、哈希
、全文索引
是咱們常常用到的。sql
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
索引的查詢spa
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
。
由於哈希索引只存儲對於的哈希值和行指針,因此哈希索引的結構很緊湊,查詢速度很是快。可是也有一些缺點。code
student
表是索引 改成 hash(first_name,last_name)
,那麼查詢必須用到first_name,last_name
纔會使用到索引。<,>
等範圍查詢是不會使用到索引的。