在MySQL中,索引(index)也叫作「鍵(key)」,它是存儲引擎用於快速找到記錄的一種數據結構。
單列索引mysql
ALTER TABLE `testDB`.`user` ADD INDEX `idx_name`(`name`) USING BTREE
組合索引redis
ADD INDEX `idx_mult`(`name`, `address`) USING BTREE
組合索引最左前綴原則
例如上面咱們建立了一個name, address的組合索引
select * from user where name = ‘xxx’ 此時,會走索引
select * from user where address = ‘xxx’ 則不會走索引算法
全文索引
首先,全文索引主要針對文本文件,好比文章,標題,全文索引只有MyISAM有效(mysql5.6以後InnoDB也支持了全文索引)sql
create table c( id int primary key auto_increment , title varchar(20), content text, fulltext(title,content) )engine=myisam charset utf8; insert into c(title,content) values ('MySQL Tutorial','DBMS stands for DataBase ...'), ('How To Use MySQL Well','After you went through a ...'), ('Optimizing MySQL','In this tutorial we will show ...'), ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), ('MySQL vs. YourSQL','In the following database comparison ...'), ('MySQL Security','When configured properly, MySQL ...');
惟一索引數據庫
ADD UNIQUE INDEX `idx_unique`(`en_name`);
主鍵是一種約束,惟一索引是一種索引,二者在本質上是不一樣的。
主鍵建立後必定包含一個惟一性索引,惟一性索引並不必定就是主鍵。
惟一性索引列容許空值,而主鍵列不容許爲空值。
主鍵列在建立時,已經默認爲空值 + 惟一索引了。
主鍵能夠被其餘表引用爲外鍵,而惟一索引不能。
一個表最多隻能建立一個主鍵,但能夠建立多個惟一索引。
主鍵更適合那些不容易更改的惟一標識,如自動遞增列、身份證號等。緩存
通常有四種索引方式(BTREE,RTREE, HASH ,FULLTEXT)
B+Tree相對於B-Tree有幾點不一樣:
非葉子節點只存儲鍵值信息。
全部葉子節點之間都有一個鏈指針。
數據記錄都存放在葉子節點中。數據結構
HASH索引工具
R-Tree索引
R-Tree在MySQL不多使用,僅支持geometry數據類型,支持該類型的存儲引擎只有MyISAM、BDb、InnoDb、NDb、Archive幾種。性能
FULLTEXT索引
即爲全文索引,目前只有MyISAM引擎支持。其能夠在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不過目前只有 CHAR、VARCHAR ,TEXT 列上能夠建立全文索引。
值得一提的是,在數據量較大時候,現將數據放入一個沒有全局索引的表中,而後再用CREATE INDEX建立FULLTEXT索引,要比先爲一張表創建FULLTEXT而後再將數據寫入的速度快不少。
它的出現是爲了解決WHERE name LIKE 「%word%"這類針對文本的模糊查詢效率較低的問題。mysql索引
(1)對於BTREE這種Mysql默認的索引方式,具備廣泛的適用性 (2)因爲FULLTEXT對中文支持不是很好,在沒有插件的狀況下,最好不要使用。其實,一些小的博客應用,只須要在數據採集時,爲其創建關鍵字列表,經過關鍵字索引,也是一個不錯的方法,至少我是常常這麼作的。 (3)對於一些搜索引擎級別的應用來講,FULLTEXT一樣不是一個好的處理方法,Mysql的全文索引創建的文件仍是比較大的,並且效率不是很高,即使是使用了中文分詞插件,對中文分詞支持也只是通常。 真要碰到這種問題,Apache的Lucene或許是你的選擇。 (4)正是由於hash表在處理較小數據量時具備無可比擬的素的優點,因此hash索引很適合作緩存(內存數據庫)。如mysql數據庫的內存版本Memsql,使用量很普遍的緩存工具Mencached,NoSql數據庫redis等,都使用了hash索引這種形式。 固然,不想學習這些東西的話Mysql的MEMORY引擎也是能夠知足這種需求的。
擴展:
1.索引沒法存儲null值
a.單列索引沒法儲null值,複合索引沒法儲全爲null的值。爲何索引列沒法存儲Null值?
a.索引是有序的。NULL值進入索引時,沒法肯定其應該放在哪裏。(將索引列值進行建樹,其中必然涉及到諸多的比較操做,null 值是不肯定值沒法比較,沒法肯定null出如今索引樹的葉子節點位置。)
b.若是須要把空值存入索引,方法有二:其一,把NULL值轉爲一個特定的值,在WHERE中檢索時,用該特定值查找。其二,創建一個複合索引。例如 create index ind_a on table(col1,1);
經過在複合索引中指定一個非空常量值,而使構成索引的列的組合中,不可能出現全空值。
不適合鍵值較少的列(重複數據較多的列)
假如索引列TYPE有5個鍵值,若是有1萬條數據,那麼 WHERE TYPE = 1將訪問表中的2000個數據塊。
再加上訪問索引塊,一共要訪問大於200個的數據塊。
若是全表掃描,假設10條數據一個數據塊,那麼只需訪問1000個數據塊,既然全表掃描訪問的數據塊少一些,確定就不會利用索引了。
索引失效的幾種狀況
1.若是條件中有or,即便其中有條件帶索引也不會使用(這也是爲何儘可能少用or的緣由),要想使用or,又想讓索引生效,只能將or條件中的每一個列都加上索引 2.對於多列索引,不是使用的第一部分,則不會使用索引 3.like查詢以%開頭(例如where code like '%AB'條件是不會走索引的,而where code like 'AB%'條件是會走索引的) 4.若是列類型是字符串,那必定要在條件中將數據使用引號引用起來,不然不使用索引 5.若是mysql估計使用全表掃描要比使用索引快,則不使用索引