mysql索引知識點匯總


一.索引基礎知識

1.什么叫數據庫索引?

答:索引是對數據庫中一列或者多列的值進行排序的一種數據結構。重點:對列的進行排序的數據結構。

使用索引可以快速訪問數據庫中的記錄

2.索引的主要用途是什么?

答:執行select語句時候會使用索引索引主要用來提高查詢性能。由於索引是經過某種算法優化過的,因而查找次數要少的多。

索引另一個主要用途是用在排序上。

3.索引是怎么執行的?

答:數據庫也是一種程序,需要在內存中運行,需要cpu和內存資源。索引被數據庫程序放到內存中,所以索引不能太大,cpu進行計算查詢,然后產生中間結果集。

索引是被數據庫程序裝載到內存中的,索引是被數據庫程序裝載到內存中的,索引是被數據庫程序裝載到內存中的,

索引文件會產生一個中間結果集,然后根據中間結果集,在表中查詢具體的記錄。

由於索引文件以B-樹格式保存,MySQL能夠立即轉到合適的firstname,然后再轉到合適的lastname,最后轉到合適的age。在沒有掃描數據文件任何一個記錄的情況下,MySQL就正確地找出了搜索的目標記錄! 

4.不使用索引情況下,sql查詢語句是怎么執行的?

答:如果沒有索引,必須遍歷整個表。例如這樣一個查詢:select * from table1 where id=10000。如果沒有索引,必須遍歷整個表,直到ID等於10000的這一行被找到為止;有了索引之后(必須是在ID這一列上建立的索引),即可在索引中查找。由於索引是經過某種算法優化過的,因而查找次數要少的多。可見,索引是用來定位的。

5.索引中記錄的順序與表中物理記錄的順序一致么?

答:當然不一致,因為索引會對字段值進行排序,且索引采用特殊的優化算法存儲。但聚集索引是不同的,聚集索引中記錄的順序與物理表中記錄的順序是一致的。與非聚集索引相比,聚集索引能提供更快的數據訪問速度。

但要注意:一個表中只能有一個聚集索引。

6.索引是怎么存儲的?

答:索引是與數據庫中的表一起存儲的.存儲在數據庫中。且索引采用二叉樹算法存儲的,方便查詢速很快。

7.索引有哪些種類?

答:可以在數據庫中添加三種索引,主鍵索引,唯一索引,聚集索引。

1)唯一索引 唯一索引是不允許其中任何兩行具有相同索引值的索引。當現有數據中存在重復的鍵值時,大多數數據庫不允許將新創建的唯一索引與表一起保存。數據庫還可能防止添加將在表中創建重復鍵值的新數據。例如,如果在employee表中職員的姓(lname)上創建了唯一索引,則任何兩個員工都不能同姓。

2)主鍵索引 數據庫表經常有一列或多列組合,其值唯一標識表中的每一行。該列稱為表的主鍵。(多列也可以作為主鍵),主鍵索引是唯一索引的特定類型。因為唯一索引要求索引列的值不能相同,而主鍵也都不相同,主鍵用來區分不同記錄,當然不能重復。故主鍵索引是唯一索引的特殊形式。

    主鍵索引是數據庫自動建立的,只要指定了主鍵,數據庫就會自動創建主鍵索引

3)聚集索引中 表中行的物理順序與鍵值的邏輯(索引)順序相同。一個表只能包含一個聚集索引。如果某索引不是聚集索引,則表中行的物理順序與鍵值的邏輯順序不匹配。與非聚集索引相比,聚集索引通常提供更快的數據訪問速度。

二.怎樣運用索引?

8.單列索引與組合索引執行效率有差別么?

答:如果在firstname、lastname、age這三個列上分別創建單列索引,效果是否和創建一個firstname、lastname、age的多列索引一樣呢?答案是否定的,兩者完全不同。當我們執行查詢的時候,MySQL只能使用一個索引。如果你有三個單列的索引,MySQL會試圖選擇一個限制最嚴格的索引。但是,即使是限制最嚴格的單列索引,它的限制能力也肯定遠遠低於firstname、lastname、age這三個列上的多列索引。

由於索引文件以B-樹格式保存,MySQL能夠立即轉到合適的firstname,然后再轉到合適的lastname,最后轉到合適的age。在沒有掃描數據文件任何一個記錄的情況下,MySQL就正確地找出了搜索的目標記錄!  

9.組合索引的好處是什么?最左前綴是什么?

答:

多列索引還有另外一個優點,它通過稱為最左前綴(Leftmost Prefixing)的概念體現出來。繼續考慮前面的例子,現在我們有一個firstname、lastname、age列上的多列索引,我們稱這個索引為fname_lname_age。當搜索條件是以下各種列的組合時,MySQL將使用fname_lname_age索引: 

firstname,lastname,age 
firstname,lastname 
firstname 

從另一方面理解,它相當於我們創建了(firstname,lastname,age)、(firstname,lastname)以及(firstname)這些列組合上的索引。下面這些查詢都能夠使用這個fname_lname_age索引: 

SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND age='17'; 
SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan'; 
SELECT peopleid FROM people WHERE firstname='Mike'; The following queries cannot use the index at all: SELECT peopleid FROM people WHERE lastname='Sullivan';
SELECT peopleid FROM people WHERE age='17'; SELECT peopleid FROM people WHERE lastname='Sullivan' AND age='17';

8.怎樣選擇索引列?(重點)

答:在性能優化過程中,選擇在哪些列上創建索引是最重要的步驟之一。可以考慮使用索引的主要有兩種類型的列:在WHERE子句中出現的列,在join子句中出現的列。

1)通常在where和join的判斷字段上,都建立索引。以方便查詢速度,在判斷條件列上使用索引,方便快定位記錄。

2)可以在一列或者多列創建索引。

如果經常同時搜索兩列或多列或按兩列或多列排序時,建立組合索引會很大提高查詢速度。例如,如果經常在同一查詢中為姓和名兩列設置判據,那么在這兩列上創建多列索引將很有意義。

3)在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;

4)在經常需要根據范圍進行搜索的列上創建索引,因為索引已經排序,其指定的范圍是連續的

SELECT age ## 不使用索引 
FROM people WHERE firstname='Mike' ## 考慮使用索引 
AND lastname='Sullivan' ## 考慮使用索引 

這個查詢與前面的查詢略有不同,但仍屬於簡單查詢。由於age是在SELECT部分被引用,MySQL不會用它來限制列選擇操作。因此,對於這個查詢來說,創建age列的索引沒有什么必要。下面是一個更復雜的例子: 

SELECT people.age, ##不使用索引 
town.name ##不使用索引 
FROM people LEFT JOIN town ON 
people.townid=town.townid ##考慮使用索引 
WHERE firstname='Mike' ##考慮使用索引 
AND lastname='Sullivan' ##考慮使用索引 


與前面的例子一樣,由於firstname和lastname出現在WHERE子句中,因此這兩個列仍舊有創建索引的必要。除此之外,由於town表的townid列出現在join子句中,因此我們需要考慮創建該列的索引。 
那么,我們是否可以簡單地認為應該索引WHERE子句和join子句中出現的每一個列呢?差不多如此,但並不完全。我們還必須考慮到對列進行比較的操作符類型。MySQL只有對以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些時候的LIKE。可以在LIKE操作中使用索引的情形是指另一個操作數不是以通配符(%或者_)開頭的情形。例如,“SELECT peopleid FROM people WHERE firstname LIKE 'Mich%';”這個查詢將使用索引,但“SELECT peopleid FROM people WHERE firstname LIKE '%ike';”這個查詢不會使用索引。 

9.哪些字段不適合加索引?

答:第一,查詢中很少使用的列不應該創建索引。

第二,對於那些只有很少數據值的列也不應該增加索引。這是因為,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行占了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。

第三,對於那些定義為text, image和bit數據類型的列不應該增加索引。這是因為,這些列的數據量要么相當大,要么取值很少,不利於使用索引。

第四,當修改性能遠遠大於檢索性能時,不應該創建索引。這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。

10.索引的返回結果是什么?

答:索引的返回結果是一個“中間結果集”,數據庫根據中間結果集再去查找數據庫中的具體表的記錄。

11.具體查詢時會選擇使用哪個索引文件?

答:每次查詢只能使用一個索引,默認數據庫會選擇限制條件最嚴格的索引。

12.怎樣判斷是否使用了索引?及查看索引的使用性能?

答:使用explain命令

EXPLAIN
SELECT * FROM mytable
WHERE category_id=1 AND user_id=2;
This is what Postgres 7.1 returns (exactlyasI expected)
NOTICE:QUERY PLAN:
Index Scan using mytable_categoryid_userid on
mytable(cost=0.00..2.02 rows=1 width=16)
EXPLAIN
以上是postgres的數據,可以看到該數據庫在查詢的時候使用了一個 索引(一個好開始),而且它使用的是創建的第二個索引。看到上面命名的好處了吧,馬上知道它使用適當的索引了。
 
13.排序分組是怎么使用索引的?
答:因為索引默認是已經自動排序的,所以在使用排序或者分組時候,用索引去查詢速度會很快,產生排序或分組的中間結果集,然后根據中間結果集定位具體的表中的記錄。
SELECT * FROM mytable
WHERE category_id=1 AND user_id=2
ORDER BY adddate DESC;
很簡單,就像為where子句中的 字段建立一個 索引一樣,也為ORDER BY的子句中的字段建立一個索引:
CREATE INDEX mytable_categoryid_userid_adddate ON mytable (category_id,user_id,adddate);
注意:"mytable_categoryid_userid_adddate"將會被截短為"mytable_categoryid_userid_addda"
 
 
本篇文章主要參考http://m.baidu.com/from=2001a/bd_page_type=1/ssid=502f54484154495350414e1309/uid=0/pu=usm%400%2Csz%401320_2003%2Cta%40iphone_1_9.0_1_11.0/baiduid=5467C9315869C7DD0A81320AA41BD30F/w=0_10_/t=iphone/l=3/tc?ref=www_iphone&lid=2148019621677310814&order=2&fm=alop&tj=www_normal_2_0_10_title&vit=osres&m=8&srd=1&cltj=cloud_title&asres=1&title=mysql%E7%B4%A2%E5%BC%95%E8%AF%A6%E8%A7%A3%28%E8%BD%AC%29-ggjucheng-%E5%8D%9A%E5%AE%A2%E5%9B%AD&dict=30&w_qd=IlPT2AEptyoA_yiMFVCwJqPg4YA0pyNR9-tOkq&sec=15308&di=a09af049d22e5ec5&bdenc=1&tch=124.1474227970972.122.366.0.0&nsrc=IlPT2AEptyoA_yixCFOxXnANedT62v3IEQGG_ytK1DK6mlrte4viZQRAZTT-RXiOJkfugTCcg2tSaC8hOnEobxB0r_-6sVse7mjb9fzwdhPsHxEMewJmQxz_XC5o&eqid=1dcf4c7718a523001000000357def2d5&wd=&clk_info=%7B%22srcid%22%3A%221599%22%2C%22tplname%22%3A%22www_normal%22%2C%22t%22%3A1474229347253%2C%22xpath%22%3A%22div-a-h3%22%7D
及百度百科“數據庫索引”,感謝原作者


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM