今天看了一篇關於mysql索引的博客,感受內容寫的很是不錯,可是排版說實話看得我頭疼,因此將其轉載過來,從新排版,方便之後若是忘了的話能夠從新溫習
博客地址:www.cnblogs.com/whgk/p/6179…html
索引用於快速找出在某個列中有一特定值的行,不使用索引,MySQL必須從第一條記錄開始讀完整個表,直到找出相關的行,表越大,查詢數據所花費的時間就越多,若是表中查詢的列有一個索引,MySQL可以快速到達一個位置去搜索數據文件,而沒必要查看全部數據,那麼將會節省很大一部分時間。mysql
例如:有一張person表,其中有2W條記錄,記錄着2W我的的信息。有一個Phone的字段記錄每一個人的電話號碼,如今想要查詢出電話號碼爲xxxx的人的信息。算法
若是沒有索引,那麼將從表中第一條記錄一條條往下遍歷,直到找到該條信息爲止。sql
若是有了索引,那麼會將該Phone字段,經過必定的方法進行存儲,好讓查詢該字段上的信息時,可以快速找到對應的數據,而沒必要在遍歷2W條數據了。其中MySQL中的索引的存儲類型有兩種:BTREE、HASH。bash
也就是用樹或者Hash值來存儲該字段,要知道其中詳細是如何查找的,就須要會算法的知識了。咱們如今只須要知道索引的做用,功能是什麼就行。函數
經過上面說的優勢和缺點,咱們應該能夠知道,並非每一個字段度設置索引就好,也不是索引越多越好,而是須要本身合理的使用。mysql索引
注意:索引是在存儲引擎中實現的,也就是說不一樣的存儲引擎,會使用不一樣的索引學習
MyISAM和InnoDB存儲引擎:只支持BTREE索引, 也就是說默認使用BTREE,不可以更換測試
MEMORY/HEAP存儲引擎:支持HASH和BTREE索引優化
索引咱們分爲四類來說
單列索引(普通索引,惟一索引,主鍵索引)、組合索引、全文索引、空間索引
一個索引只包含單個列,但一個表中能夠有多個單列索引。 這裏不要搞混淆了。
在表中的多個字段組合上建立的索引,只有在查詢條件中使用了這些字段的左邊字段時,索引纔會被使用,使用組合索引時遵循最左前綴集合。這個若是還不明白,等後面舉例講解時在細說
全文索引,只有在MyISAM引擎上才能使用,只能在CHAR,VARCHAR,TEXT類型字段上使用全文索引,介紹了要求,說說什麼是全文索引,就是在一堆文字中,經過其中的某個關鍵字等,就能找到該字段所屬的記錄行,好比有"好人,二貨 ..."
經過好人,可能就能夠找到該條記錄。這裏說的是可能,由於全文索引的使用涉及了不少細節,咱們只須要知道這個大概意思,若是感興趣進一步深刻使用它,那麼看下面測試該索引時,會給出一個博文,供你們參考。
空間索引是對空間數據類型的字段創建的索引,MySQL中的空間數據類型有四種,GEOMETRY、POINT、LINESTRING、POLYGON。在建立空間索引時,使用SPATIAL關鍵字。要求,引擎爲MyISAM,建立空間索引的列,必須將其聲明爲NOT NULL。具體細節看下面
格式:CREATE TABLE 表名[字段名 數據類型] [UNIQUE|FULLTEXT|SPATIAL|...] [INDEX|KEY] [索引名字] (字段名[length]) [ASC|DESC]
|--------------------------------------| |-----------------------------------| |------------| |---------| |---------------| |------------|
普通建立表語句 設置什麼樣的索引(惟1、全文等) 索引關鍵字 索引名字 對哪一個字段設置索引 對索引進行排序
CREATE TABLE book
(
bookid INT NOT NULL,
bookname VARCHAR(255) NOT NULL,
authors VARCHAR(255) NOT NULL,
info VARCHAR(255) NULL,
comment VARCHAR(255) NULL,
year_publication YEAR NOT NULL,
INDEX(year_publication)
)
CREATE TABLE book
(
bookid INT NOT NULL,
bookname VARCHAR(255) NOT NULL,
authors VARCHAR(255) NOT NULL,
info VARCHAR(255) NULL,
comment VARCHAR(255) NULL,
year_publication YEAR NOT NULL,
KEY(year_publication)
)
複製代碼
上面兩種方式建立均可以,經過這個例子能夠對比一下格式,就差很少明白格式是什麼意思了。
經過打印結果,咱們在建立索引時沒寫索引名的話,會自動幫咱們用字段名看成索引名。 測試:看是否使用了索引進行查詢。
SELECT * FROM book WHERE year_publication = 1990\G;
複製代碼
解釋:雖然表中沒數據,可是有EXPLAIN關鍵字,用來查看索引是否正在被使用,而且輸出其使用的索引的信息。
id:SELECT識別符。這是SELECT的查詢序列號,也就是一條語句中,該select是第幾回出現
。在這條語句中,select就只有一個,因此是1.
select_type:所使用的SELECT查詢類型,SIMPLE表示爲簡單的SELECT,不使用UNION或子
查詢,就爲簡單的SELECT。也就是說在該SELECT查詢時會使用索引。其餘取值,
PRIMARY:最外面的SELECT.在擁有子查詢時,就會出現兩個以上的SELECT。UNION:union
(兩張錶鏈接)中的第二個或後面的select語句 SUBQUERY:在子查詢中,第二SELECT。
table:數據表的名字。他們按被讀取的前後順序排列,這裏由於只查詢一張表,因此只
顯示book
type: 指定本據表和其餘數據表之間的關聯關係,該表中全部符合檢索值的記錄都會被取
出來和從上一個表中取出來的記錄做聯合。ref用於鏈接程序使用鍵的最左前綴或者是該
鍵不是 primary key 或unique索引(換句話說,就是鏈接程序沒法根據鍵值只取得一條
記錄)的狀況。當根據鍵值只查詢到少數幾條匹配的記錄時,這就是一個不錯的鏈接類型
。(注意,我的這裏不是很理解,百度了不少資料,全是大白話,等之後用到了這類信息
時,在回過頭來補充,這裏不懂對後面的影響不大。)可能的取值有
system、const、eq_ref、index和All
possible_keys:MySQL在搜索數據記錄時能夠選用的各個索引,該表中就只有一個索引,y
ear_publication
key:實際選用的索引
key_len:顯示了mysql使用索引的長度(也就是使用的索引個數),當key字段的值爲null
時,索引的長度就是null。注意,key_len的值能夠告訴你在聯合索引中mysql會真正使用
了哪些索引。這裏就使用了1個索引,因此爲1,
ref:給出關聯關係中另外一個數據表中數據列的名字。常量(const),這裏使用的是1990
,就是常量。
rows:MySQL在執行這個查詢時預計會從這個數據表裏讀出的數據行的個數。
extra:提供了與關聯操做有關的信息,沒有則什麼都不寫。
上面的一大堆東西能看懂多少看多少,咱們最主要的是看possible_keys和key 這兩個屬性,上面顯示了key爲year_publication。說明使用了索引。
複製代碼
CREATE TABLE t1
(
id INT NOT NULL,
name CHAR(30) NOT NULL,
UNIQUE INDEX UniqIdx(id)
)
複製代碼
解釋:對id字段使用了索引,而且索引名字爲UniqIdx。
SHOW CREATE TABLE t1\G;
複製代碼
要查看其中查詢時使用的索引,必須先往表中插入數據,而後在查詢數據,否則查找一個沒有的id值,是不會使用索引的。
INSERT INTO t1 VALUES(1,'xxx');
EXPLAIN SELECT * FROM t1 WHERE id = 1\G;
複製代碼
能夠看到,經過id查詢時,會使用惟一索引。而且還實驗了查詢一個沒有的id值,則不會使用索引,我以爲緣由是全部的id應該會存儲到一個const tables中,到其中並無該id值,那麼就沒有查找的必要了。
CREATE TABLE t2
(
id INT NOT NULL,
name CHAR(10),
PRIMARY KEY(id)
);
INSERT INTO t2 VALUES(1,'QQQ');
EXPLAIN SELECT * FROM t2 WHERE id = 1\G;
複製代碼
經過這個主鍵索引,咱們就應該反應過來,其實咱們之前聲明的主鍵約束,就是一個主鍵索引,只是以前咱們沒學過,不知道而已。
這個其實就不用在說了,前面幾個就是單列索引。
*建立組合索引
組合索引就是在多個字段上建立一個索引
建立一個表t3,在表中的id、name和age字段上創建組合索引
CREATE TABLE t3
(
id INT NOT NULL,
name CHAR(30) NOT NULL,
age INT NOT NULL,
info VARCHAR(255),
INDEX MultiIdx(id,name,age)
);
SHOW CREATE t3\G;
複製代碼
解釋最左前綴
組合索引就是聽從了最左前綴,利用索引中最左邊的列集來匹配行,這樣的列集稱爲最左前綴,不明白不要緊,舉幾個例子就明白了,例如,這裏由id、name和age3個字段構成的索引,索引行中就按id/name/age的順序存放,索引能夠索引下面字段組合(id,name,age)、(id,name)或者(id)。若是要查詢的字段不構成索引最左面的前綴,那麼就不會是用索引,好比,age或者(name,age)組合就不會使用索引查詢
在t3表中,查詢id和name字段
EXPLAIN SELECT * FROM t3 WHERE id = 1 AND name = 'joe'\G;
複製代碼
在t3表中,查詢(age,name)字段,這樣就不會使用索引查詢。來看看結果
EXPLAIN SELECT * FROM t3 WHERE age = 3 AND name = 'bob'\G;
複製代碼
全文索引能夠用於全文搜索,但只有MyISAM存儲引擎支持FULLTEXT索引,而且只爲CHAR、VARCHAR和TEXT列服務。索引老是對整個列進行,不支持前綴索引,
CREATE TABLE t4
(
id INT NOT NULL,
name CHAR(30) NOT NULL,
age INT NOT NULL,
info VARCHAR(255),
FULLTEXT INDEX FullTxtIdx(info)
)ENGINE=MyISAM;
SHOW CREATE TABLE t4\G;
複製代碼
使用一下什麼叫作全文搜索。就是在不少文字中,經過關鍵字就可以找到該記錄。
INSERT INTO t4 VALUES
(8,'AAA',3,'text is so good,hei,my name is bob')
,(9,'BBB',4,'my name is gorlr');
SELECT * FROM t4 WHERE MATCH(info) AGAINST('gorlr');
複製代碼
EXPLAIN SELECT * FROM t4 WHERE MATCH(info) AGAINST('gorlr');
複製代碼
注意:在使用全文搜索時,須要藉助MATCH函數,而且其全文搜索的限制比較多,好比只能經過MyISAM引擎,好比只能在CHAR,VARCHAR,TEXT上設置全文索引。好比搜索的關鍵字默認至少要4個字符,好比搜索的關鍵字過短就會被忽略掉。等等,若是大家在實驗的時候可能會實驗不出來。感興趣的同窗能夠看看這篇文章,
全文搜索的使用
空間索引也必須使用MyISAM引擎, 而且空間類型的字段必須爲非空。
這個空間索引具體能幹嗎我也不知道,可能跟遊戲開發有關,可能跟別的東西有關,等遇到了天然就知道了,如今只要求可以建立出來。
CREATE TABLE t5
(
g GEOMETRY NOT NULL,
SPATIAL INDEX spatIdx(g)
) ENGINE = MyISAM;
SHOW CREATE TABLE t5\G;
複製代碼
格式:ALTER TABLE 表名 ADD[UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] [索引名] (索引字段名)[ASC|DESC] 有了上面的基礎,這裏就不用過多陳述了。
命令一:
SHOW INDEX FROM 表名\G
複製代碼
查看一張表中所建立的索引
SHOW INDEX FROM book\G;
複製代碼
挑重點講,咱們須要瞭解的就5個,用紅顏色標記了的,若是想深刻了解,能夠去查查該方面的資料,我我的以爲,這些等之後實際工做中遇到了在作詳細的瞭解把。
Table:建立索引的表
Non_unique:表示索引非惟一,1表明非惟一索引,0表明惟一索引,意思就是該索引是否是惟一索引
Key_name:索引名稱
Seq_in_index :表示該字段在索引中的位置,單列索引的話該值爲1,組合索引爲每一個字段在索引定義中的順序(這個只須要知道單列索引該值就爲1,組合索引爲別的)
Column_name:表示定義索引的列字段
Sub_part:表示索引的長度
Null:表示該字段是否能爲空值
Index_type:表示索引類型
複製代碼
就拿上面的book表來講。原本已經有了一個year_publication,如今咱們爲該表在加一個普通索引
ALTER TABLE book ADD INDEX BkNameIdx(bookname(30));
複製代碼
看輸出結果,就能知道,添加索引成功了。
這裏只是拿普通索引作個例子,添加其餘索引也是同樣的。依葫蘆畫瓢而已。這裏就不一一作講解了。
格式:CREATE [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] 索引名稱 ON 表名(建立索引的字段名[length])[ASC|DESC]
解釋:其實就是換湯不換藥,格式改變了一下而已,作的事情跟上面徹底同樣,作一個例子。
在爲book表增長一個普通索引,字段爲authors。
CREATE INDEX BkBookNameIdx ON book(bookname);
複製代碼
SHOW INDEX FROM book\G;  //查看book表中的索引
複製代碼
解釋:第一條截圖沒截到,由於圖太大了,這裏只要看到有咱們新加進去的索引就證實成功了。。其餘索引也是同樣的建立。
前面講了對一張表中索引的添加,查詢的方法。
添加的兩種方式
1在建立表的同時如何建立索引,
2在建立了表以後如何給表添加索引的兩種方式,
查詢的方式
SHOW INDEX FROM 表名\G;
複製代碼
\G只是讓輸出的格式更好看
如今來講說如何給表刪除索引的兩種操做。
很簡單的語句,如今經過一個例子來看看,仍是對book表進行操做,刪除咱們剛纔爲其添加的索引。
一、刪除book表中的名稱爲BkBookNameIdx的索引。
ALTER TABLE book DROP INDEX BkBookNameIdx;
複製代碼
SHOW INDEX FROM book\G;  //在查看book表中的索引,就會發現BkBookNameIdx這個索引已經不在了
複製代碼
刪除book表中名爲BkNameIdx的索引
DROP INDEX BkNameIdx ON book;
SHOW INDEX FROM book\G;
複製代碼