MySQL(七)------ 索引的設計和使用
阿新 • • 發佈:2018-12-20
索引是資料庫中用來提高效能的最常用工具,下面簡單介紹一下索引的型別和設計原則。
一、索引概述
特點 | MyISAM | InnoDB | MEMORY | MERGE |
---|---|---|---|---|
B樹索引 | 支援(預設) | 支援(預設) | 支援 | 支援 |
雜湊索引 | 支援(預設) | |||
全文索引 | 支援 | |||
字首索引 | 支援 | 支援 |
索引在建立表的時候可以同時建立,也可以隨時增加新的索引,建立新索引的語法為:
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON tbl_name( col_name [(length)] [ASC|DESC])
使用ALTER TABLE 語法來增加索引,與上面類似。
mysql> create index cityname on city (city(10)); Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> explain select * from city where city = 'FUzhou' \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: city partitions: NULL type: ref possible_keys: cityname key: cityname key_len: 32 ref: const rows: 1 filtered: 100.00 Extra: Using where 1 row in set, 1 warning (0.00 sec)
刪除索引的語法為:
DROP INDEX index_name ON tbl_name
mysql> drop index cityname on city;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
二、索引設計的原則
下面列出的是一些已有的原則,建立索引時儘量遵守以便提升效率。
- 最適合索引的列是出現在WHERE字句中的列,或連線字句中指定的列,而不是出現在SELECT關鍵字後選擇列表中的列。
- 使用唯一索引;主要考慮索引列中值的唯一性,比如用生日列做索引搜尋出來的結果往往比用性別做索引搜尋出來的要好,因為性別不管搜尋哪個值都會出來一半結果。
- 使用短索引;比如對較長字串列進行索引,一般都是對一定長度的字首進行索引,或是之前提到過的用雜湊值進行索引,這樣有助於減少磁碟IO,節省空間及記憶體,加快查詢速度。
- 不要過度索引;索引不是越多越好,每個索引都要佔用額外的磁碟空間,並降低寫操作的效能,而且每當表內容有變化時索引都要進行更新,從而使得花費時間更長;所以只保留所需索引才是最佳的。
- 對於InnoDB型別的表,如果有主鍵則按主鍵順序儲存;如果沒有主鍵但有唯一索引,那麼就按唯一索引的順序儲存;如果兩個都沒有,那就會按表中自動生成的內部列的順序來儲存。儘量定義主鍵,它的訪問速度最快,而且一般用最常作為訪問條件的列做主鍵,且需要選擇較短的資料型別,這樣做都是為了節省空間提高速度。
三、BTREE索引與HASH索引
MEMORY型別表同時支援BTREE索引和HASH索引,這兩個索引也有一些不同的適應範圍。
HASH索引需要注意:
- 只用於使用=或<=>操作符的等式比較;
- 優化器不能使用HASH索引來加速ORDER BY操作;
- 只能使用整個關鍵字來搜尋一行;
- 不能確定兩個值之間大約有多少行;
而BTREE索引就可以使用範圍搜尋和模糊搜尋,並使用相關列上的索引。
看下面的例子:
下列範圍查詢BTREE索引和HASH索引都適用:
select * from t1 where key_col=1,or key_col in (15,18,20);
下列範圍查詢只適合BTREE索引:
select * from t1 where key_col > 1 and key_col < 10;
select * from t1 where key_col like 'ab%' or key_col between 'lisa' and 'simon';
當我們建立一個MEMORY型別的表時,預設使用的是HASH索引,而此時如果對索引欄位進行範圍查詢,此時的HASH沒有起到作用,實際上還是進行的全表掃描;只有將其改為BTREE索引時才可以有效通過索引來提高效率。
因此,如果建立MEMORY表,就需要注意SQL語句的編寫確保能使用上索引;如果一定要使用範圍查詢,那麼應該建立成BTREE索引的表。