PS:上網再次看了一下數據庫關於索引的一些細節...感受本身學的東西有點少...又再次的啃了啃索引....
mysql
學習內容:sql
索引查詢優化...數據庫
上一章說道的索引還不是特別的詳細,再補充一些具體的細節...緩存
1.B-Tree索引...數據結構
B-tree結構被稱爲平衡多路查找樹...其數據結構爲:函數
這就是其數據結構圖。。。咱們不必徹底的理解其中的原理。。而且我也不會作過多的原理介紹。。。咱們只須要知道數據庫是以這種方式進行存儲數據的就能夠了...工具
mysql> create table title -> ( -> id int not null, -> title varchar(255) not null, -> from_date date not null, -> key(id), -> key(title), -> key(from_date) -> ); //創建一個表格。。。有三個主鍵..。有主鍵必然要使用到索引... 介紹一下查詢方式... 1.全列匹配... mysql>expla select * from title where id=1000 and title='gogoing' and from_date='1992-01-01'; +----+-------------+--------+-------+---------------+---------+---------+-------------------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+-------+---------------+---------+---------+-------------------+------+-------+ | 1 | SIMPLE | titles | const | PRIMARY | PRIMARY | 59 | const,const,const | 1 | | +----+-------------+--------+-------+---------------+---------+---------+-------------------+------+-------+ 2.最左前綴索引... explain select * from title where id=1001; +----+-------------+--------+------+---------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+------+---------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | titles | ref | PRIMARY | PRIMARY | 4 | const | 1 | | +----+-------------+--------+------+---------------+---------+---------+-------+------+-------+ 最左前綴原則是當索引用到多個列的時候,只有組成最左前綴的部分才能被使用到..上面只用到了第一列... 3.匹配的索引列使用了精確匹配。。。可是中間有部分列沒有被給出... explain select * from title where id=1002 and from_date='1998-01-01'; +----+-------------+--------+------+---------------+---------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+------+---------------+---------+---------+-------+------+-------------+ | 1 | SIMPLE | titles | ref | PRIMARY | PRIMARY | 4 | const | 1 | Using where | +----+-------------+--------+------+---------------+---------+---------+-------+------+-------------+ 這樣只會走第一個索引id,而from_date將不走索引。。因爲沒有給出title的值,因此沒法構成最左前綴原則,所以from_date成爲不走索引... 咱們可使用兩種方式解決這個問題....使用IN將title的全部值都包括在其中... EXPLAIN SELECT * FROM employees.titles WHERE emp_no='1005' AND title IN ('title1的值','title2的值'......) AND from_date='1986-06-26'; +----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+ | 1 | SIMPLE | titles | range | PRIMARY | PRIMARY | 59 | NULL | 7 | Using where | +----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+ 這樣就不會出現不走索引的狀況了...可是若是title的值過多,那麼in這種方式就不能使用..所以解決這個問題的另外一種方式就是創建輔助索引.... 4.查詢的時候沒有指定索引的第一列... explain select * from title where from_date='1995-01-26';//這個結果很明顯,就是不走索引... 5.匹配某列前綴的字符串.. explain select * from title where id=1008 and title like 'S%'; +----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+ | 1 | SIMPLE | titles | range | PRIMARY | PRIMARY | 56 | NULL | 1 | Using where | +----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+ 6.使用範圍查詢... explain select * from title where id>1010;範圍列可使用索引,可是必須是最左前綴..而且若是同一個查詢語句使用了兩個範圍索引,那麼後面的範圍將成爲不走索引.. explain select * from title where id>1010 and title='gogoing' and from_date between '1990-01-01' and '1998-01-01'; 還有一種狀況就是以下面代碼.. explain select * from where id between 1000 and 1010 and title='gogoing' and from_date between '1998-01-01' and '2010-01-01'; 上面這種狀況就變成了第一個就成爲了多值匹配,然後面那個範圍成爲了範圍匹配...一樣都是兩個範圍匹配,和上面的狀況就不一樣了..這個我至今沒弄明白..雲裏霧裏的...若是有大牛會的話請告訴我。。。 7.帶有表達式的查詢方式... 若是查詢語句中含有表達式,那麼將成爲不走索引。。。(除一些特殊方式)。。。 EXPLAIN SELECT * FROM employees.titles WHERE emp_no - 1='10000'; +----+-------------+--------+------+---------------+------+---------+------+--------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+------+---------------+------+---------+------+--------+-------------+ | 1 | SIMPLE | titles | ALL | NULL | NULL | NULL | NULL | 443308 | Using where | +----+-------------+--------+------+---------------+------+---------+------+--------+-------------+ 不走索引...
2.Hash索引..性能
MySQL中,只有Memory存儲引擎顯示支持hash索引,是Memory表的默認索引類型,儘管Memory表也可使用B-Tree索引。 Memory存儲引擎支持非惟一hash索引,這在數據庫領域是罕見的,若是多個值有相同的hash code,索引把它們的行指針用鏈表保存到同一個hash表項中。。學習
hash索引就是講咱們存儲的數據按照必定的哈希函數來進行保存在一個指針數據中,當咱們須要查找的時候,調用hash函數,找到咱們須要的數據的指針,經過這個指針,咱們就能夠訪問其中的數據信息了..hash的指針數據是有序的,但對應的數據信息是無序的...優化
Hash索引有如下一些限制:
(1)因爲索引僅包含hash code和記錄指針,因此,MySQL不能經過使用索引避免讀取記錄。可是訪問內存中的記錄是很是迅速的,不會對性形成太大的影響。
(2)不能使用hash索引排序。
(3)Hash索引不支持鍵的部分匹配,由於是經過整個索引值來計算hash值的。
(4)Hash索引只支持等值比較,例如使用=,IN( )和<=>。對於WHERE price>100並不能加速查詢。
3.索引的使用範圍...
那麼咱們到底什麼狀況下使用索引呢?有兩種判斷的方式...
i.看了別人的博客說。。通常當咱們存儲的數據不超過2000條的時候,咱們是沒有必要使用索引的...
ii.索引的選擇性。。。
索引的選擇性=表中列的惟一鍵的數量/表的行數...這個數值越接近於1越好...就好比說主鍵,毋庸置疑絕對是1..因此有了主鍵咱們必需要使用索引..
上面說到了輔助索引...
4.那麼什麼是輔助索引呢?簡單的介紹一下....
不一樣的存儲引擎對應的輔助索引的結構圖也是不一樣的。。。其實輔助索引和主索引並無過大的區別,只是主索引要求key值惟一。。輔助索引的key值能夠重複....而且兩者構成的存儲結構也基本相同,都是一棵b+tree。。。每個數據記錄都保存在一個地址當中,這個地址的獲取由地址節點的父節點來存儲...一層扣一層。。。就造成了樹狀結構...
5.聚簇索引..
Innobe存儲引擎支持聚簇索引,這種索引方式也是以b+tree爲存儲結構,可是他和myisam存儲引擎徹底不一樣,由於myisam不支持聚簇索引,支持非聚簇索引...
Innobe的數據文件自己就是索引文件..這個b+tree的data數據域徹底保存着數據記錄,而且也保存着索引的key值,那麼當咱們找到了key值的時候,咱們就能夠直接訪問數據文件。。。由於數據文件的自己就是主索引...
而myisam存儲引擎的數據文件和索引文件是徹底分離的,b+tree的data數據域保存着記錄數據文件的地址,當咱們要經過索引key的值查找數據的時候,咱們須要通過找到這個key對應的data數據域的指針值,而後咱們經過指針的值去訪問咱們想要的數據信息...
聚簇索引和非聚簇索引的區別圖...Primary key表示主索引...Secondary key表示輔助索引...
6.覆蓋索引
簡單的介紹一下覆蓋索引的有點。。。本身學的也不是特別的透徹,只是作簡單的介紹...
若是索引包含知足查詢的全部數據,就稱爲覆蓋索引。覆蓋索引是一種很是強大的工具,能大大提升查詢性能。只須要讀取索引而不用讀取數據有如下一些優勢:
(1)索引項一般比記錄要小,因此MySQL訪問更少的數據;
(2)索引都按值的大小順序存儲,相對於隨機訪問記錄,須要更少的I/O;
(3)大多數據引擎能更好的緩存索引。好比MyISAM只緩存索引。
(4)覆蓋索引對於InnoDB表尤爲有用,由於InnoDB使用匯集索引組織數據,若是二級索引中包含查詢所需的數據,就再也不須要在彙集索引中查找了。
覆蓋索引不能是任何索引,只有B-TREE索引存儲相應的值。並且不一樣的存儲引擎實現覆蓋索引的方式都不一樣,並非全部存儲引擎都支持覆蓋索引(Memory和Falcon就不支持)。
對 於索引覆蓋查詢(index-covered query),使用EXPLAIN時,能夠在Extra一列中看到「Using index」。
7.利用索引進行排序...
MySQL中,有兩種方式生成有序結果集:一是使用filesort,二是按索引順序掃描。利用索引進行排序操做是很是快的,並且能夠利用同一索引同時進 行查找和排序操做。當索引的順序與ORDER BY中的列順序相同且全部的列是同一方向(所有升序或者所有降序)時,可使用索引來排序。若是查詢是鏈接多個表,僅當ORDER BY中的全部列都是第一個表的列時纔會使用索引。其它狀況都會使用filesort。
create table actor( actor_id int unsigned NOT NULL AUTO_INCREMENT, name varchar(16) NOT NULL DEFAULT '', password varchar(16) NOT NULL DEFAULT '', PRIMARY KEY(actor_id), KEY (name) ) ENGINE=InnoDB insert into actor(name,password) values('cat01','1234567'); insert into actor(name,password) values('cat02','1234567'); insert into actor(name,password) values('ddddd','1234567'); insert into actor(name,password) values('aaaaa','1234567'); mysql> explain select actor_id from actor order by actor_id; +----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ | 1 | SIMPLE | actor | index | NULL | PRIMARY | 4 | NULL | 4 | Using index | +----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+ mysql> explain select actor_id from actor order by password; +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | 1 | SIMPLE | actor | ALL | NULL | NULL | NULL | NULL | 4 | Using filesort | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ mysql> explain select actor_id from actor order by name; +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | actor | index | NULL | name | 34 | NULL | 4 | Using index | +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+