1.索引基礎sql
索引對於良好的性能很是關鍵。尤爲是當表中的數據量愈來愈大時,索引對性能的影響愈發重要。可是不恰當的索引隨着數據量的增長,也會使整個數據庫的性能降低。數據庫
舉個例子:性能優化
select a from b where id = 5;
若是在id上創建索引,則Mysql會使用該索引找到id爲5的行,也就是說,Mysql如今索引按值進行查找,而後返回全部包含該值的數據行。索引也能夠包含一列或者多列,列的順序也十分重要,由於Mysql只能高效地使用索引的最左前綴列。性能
索引優化應該是查詢性能優化最有效的手段了,一個「最優」的索引有時比一個「好的」索引性能要好兩個數量級,因此索引的學習不管對開發者或者DBA來講都極爲重要。學習
2.索引類型優化
B-Tree索引url
人們在談論索引時,若無指定,通常爲B-Tree類型的索引,Mysql大部分引擎支持B-Tree索引,但在不一樣的存儲引擎中,B-Tree也可能以不一樣存儲結構實現,好比InnoDB則使用B+Tree。存儲引擎以不一樣的方式使用B-Tree索引,性能優劣各有不一樣。spa
B-Tree一般意味着全部的值都是按順序存儲的,而且每個葉子頁到根的距離相同。下圖爲B-Tree(B+Tree)索引的抽象表示,大體反映了InnoDB索引是如何工做的。MyISAM使用的結構有所不一樣,但基本思想是相似的。指針
這種類型的索引的好處是查詢時不須要進行全盤掃描而是從根節點開始搜索,經過比較找到相應的值並進入下層子節點。因此B-Tree比較適合查找範圍數據,例如像「找出全部I到K開頭的名字」。code
假設有以下數據表:
CREATE TABLE People ( last_name varcher(50) not null, first_name varcher(50) not null, dob date not null, gender enum('m', 'f') not null, key(last_name, first_name, dob) );
對於表中的每一行數據,索引中包含了last_name,first_name,dob列的值,下圖顯示了該索引是如何組織數據的存儲的。
下面列舉一些B-Tree索引的經常使用的查詢類型:
除了按值查找外,索引還能夠用於ORDER BY操做。
下列關於B-Tree索引的一些限制:
哈希索引
哈希索引基於哈希表實現,只有精確匹配索引全部列的查詢纔有效。在Mysql中只有Memory引擎顯式支持哈希索引。
好比: SELECT A FROM B WHERE name='PETER';
Mysql會先計算'PETER'的哈希值,並使用該值尋找對應的指針記錄。由於索引自身只需存儲對應的哈希值,因此哈希索引查找速度很是快,可是也有一些限制:
由於這些限制,哈希索引使用的場景有限,而一旦適合哈希索引時,則它帶來的性能提高將很是高。
固然,對於InnoDB來講也能夠建立一個僞哈希列來進行排序查找也是能夠的。
下面有個實例,例如須要存儲大量URL,若是使用B-Tree來存儲URL,存儲的內容會很大,由於URL自己很長,正常狀況下會有以下查詢:
SELECT ID FORM URL WHERE url='http://www.baidu.com'
若刪除原來的URL列上的索引,而新增一個被索引的url_crc列,使用CRC32作哈希,就可使用下面的方式查詢:
SELECT ID FROM URL WHERE url='http://www.baidu.com' AND url_crc=CRC32("http://www.baidu.com");
這樣作的性能會比單獨在url列上開索引高不少,但缺陷就是須要維護哈希值,能夠手動維護,也可使用觸發器實現,例如:
//建立表 CREATE TABLE pseudo hash( id int unsigned not null auto_increment, url archer(255) not null, url_crc int unsigned not null default 0, primary key(id) ); //建立觸發器 DELIMITER // CREATE TRIGGER pseudohash_crc_ins BEFORE INSERT ON pseudohash FOR EACH ROW BEGIN SET NEW.url_crc=crc32(NEW.url); END; // CREATE TRIGGER pseudohash_crc_upd BEFORE UPDATE ON pseudohash FOR ROW BEGIN SET NEW.url_crc=crc32(NEW.url); END; // DELIMITER ;
若是數據表很是大,crc32可能也會出現大量的哈希衝突,這個時候也可使用其餘方案代替,好比md5
處理哈希衝突時,必須在WHERE子句中包含常量值:
SELECT ID FROM URL WHERE url_crc=crc32('http://www.baidu.com') AND url='http://www.baidu.com';
還有一些其餘的索引類型,例如空間數據索引,全文索引,這裏暫時不介紹了,你們能夠自行搜索。