一.索引基礎知識
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命令