什麼是索引?
索引用來快速地尋找那些具有特定值的記錄,所有mysql索引都以b-樹的形式儲存。如果沒有索引,執行查詢時mysql必須從第乙個記錄開始掃瞄整個表的所有記錄,直至找到符合要求的記錄。表裡面的記錄數量越多,這個操作的代價就越高。如果作為搜尋條件的列上已經建立了索引,mysql無需掃瞄任何記錄即可迅速得到目標記錄所在的位置。如果表有1000個記錄,通過索引查詢記錄至少要比順序掃瞄記錄快100倍。
假設我們建立了乙個名為people的表:
create table people ( peopleid smallint not null, name char(50) not null );然後,我們完全隨機把1000個不同name值插入到people表。下圖顯示了people表所在資料檔案的一小部分:
可以看到,在資料檔案中name列沒有任何明確的次序。如果我們建立了name列的索引,mysql將在索引中排序name列:
對於索引中的每一項,mysql在內部為它儲存乙個資料檔案中實際記錄所在位置的「指標」。因此,如果我們要查詢name等於「mike」記錄的peopleid(sql命令為「select peopleid from people where name='mike';」),mysql能夠在name的索引中查詢「mike」值,然後直接轉到資料檔案中相應的行,準確地返回該行的peopleid(999)。在這個過程中,mysql只需處理乙個行就可以返回結果。如果沒有「name」列的索引,mysql要掃瞄資料檔案中的所有記錄,即1000個記錄!顯然,需要mysql處理的記錄數量越少,則它完成任務的速度就越快。
索引的型別
mysql提供多種索引型別供選擇:
普通索引
這是最基本的索引型別,而且它沒有唯一性之類的限制。普通索引可以通過以下幾種方式建立:
建立索引,例如create index 《索引的名字》 on tablename (列的列表);唯一性索引修改表,例如alter table tablename add index [索引的名字] (列的列表);
建立表的時候指定索引,例如create table tablename ( [...], index [索引的名字] (列的列表) );
這種索引和前面的「普通索引」基本相同,但有乙個區別:索引列的所有值都只能出現一次,即必須唯一。唯一性索引可以用以下幾種方式建立:
建立索引,例如create unique index 《索引的名字》 on tablename (列的列表);主鍵修改表,例如alter table tablename add unique [索引的名字] (列的列表);
建立表的時候指定索引,例如create table tablename ( [...], unique [索引的名字] (列的列表)
);
主鍵是一種唯一性索引,但它必須指定為「primary key」。如果你曾經用過auto_increment型別的列,你可能已經熟悉主鍵之類的概念了。主鍵一般在建立表的時候指定,例如「create table tablename ( [...], primary key (列的列表) ); 」。但是,我們也可以通過修改表的方式加入主鍵,例如「alter table tablename add primary key (列的列表); 」。每個表只能有乙個主鍵。
全文索引單列索引與多列索引
索引可以是單列索引,也可以是多列索引。下面我們通過具體的例子來說明這兩種索引的區別。假設有這樣乙個people表:
create table people ( peopleid smallint not null auto_increment, firstname char(50)下面是我們插入到這個people表的資料:not null, lastname char(50) not null, age smallint not null, townid smallint not
null, primary key (peopleid) );
這個資料片段中有四個名字為「mikes」的人(其中兩個姓sullivans,兩個姓mcconnells),有兩個年齡為17歲的人,還有乙個名字與眾不同的joe smith。
這個表的主要用途是根據指定的使用者姓、名以及年齡返回相應的peopleid。例如,我們可能需要查詢姓名為mike sullivan、年齡17歲使用者的peopleid(sql命令為select peopleid from people where firstname='mike' and lastname='sullivan' and age=17;)。由於我們不想讓mysql每次執行查詢就去掃瞄整個表,這裡需要考慮運用索引。
首先,我們可以考慮在單個列上建立索引,比如firstname、lastname或者age列。如果我們建立firstname列的索引(alter table people add index firstname (firstname);),mysql將通過這個索引迅速把搜尋範圍限制到那些firstname='mike'的記錄,然後再在這個「中間結果集」上進行其他條件的搜尋:它首先排除那些lastname不等於「sullivan」的記錄,然後排除那些age不等於17的記錄。當記錄滿足所有搜尋條件之後,mysql就返回最終的搜尋結果。
由於建立了firstname列的索引,與執行表的完全掃瞄相比,mysql的效率提高了很多,但我們要求mysql掃瞄的記錄數量仍舊遠遠超過了實際所需要的。雖然我們可以刪除firstname列上的索引,再建立lastname或者age列的索引,但總地看來,不論在哪個列上建立索引搜尋效率仍舊相似。
為了提高搜尋效率,我們需要考慮運用多列索引。如果為firstname、lastname和age這三個列建立乙個多列索引,mysql只需一次檢索就能夠找出正確的結果!下面是建立這個多列索引的sql命令:
alter table people add index fname_lname_age (firstname,lastname,age);最左字首
多列索引還有另外乙個優點,它通過稱為最左字首(leftmost prefixing)的概念體現出來。繼續考慮前面的例子,現在我們有乙個firstname、lastname、age列上的多列索引,我們稱這個索引為fname_lname_age。當搜尋條件是以下各種列的組合時,mysql將使用fname_lname_age索引:
firstname,lastname,age從另一方面理解,它相當於我們建立了(firstname,lastname,age)、(firstname,lastname)以及(firstname)這些列組合上的索引。下面這些查詢都能夠使用這個fname_lname_age索引:firstname,lastname
firstname
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';
在效能優化過程中,選擇在哪些列上建立索引是最重要的步驟之一。可以考慮使用索引的主要有兩種型別的列:在where子句中出現的列,在join子句中出現的列。請看下面這個查詢:
select age ## 不使用索引 from people where firstname='mike' ## 考慮使用索引 and這個查詢與前面的查詢略有不同,但仍屬於簡單查詢。由於age是在select部分被引用,mysql不會用它來限制列選擇操作。因此,對於這個查詢來說,建立age列的索引沒有什麼必要。下面是乙個更複雜的例子:lastname='sullivan' ## 考慮使用索引
select people.age, ##不使用索引 town.name ##不使用索引 from people left join town on與前面的例子一樣,由於firstname和lastname出現在where子句中,因此這兩個列仍舊有建立索引的必要。除此之外,由於town表的townid列出現在join子句中,因此我們需要考慮建立該列的索引。people.townid=town.townid ##考慮使用索引 where firstname='mike' ##考慮使用索引 and
lastname='sullivan' ##考慮使用索引
MySQL索引分析和優化
索引 索引用來快速地尋找那些具備特定值的記錄,任何mysql索引都以b 樹的形式儲存。假如沒有索引,執行查詢時mysql必須從第乙個記錄開始掃瞄整個表的任何記錄,直至找到符合需要的記錄。表裡面的記錄數量越多,這個操作的代價就越高。假如作為搜尋條件的列上已建立了索引,mysql無需掃瞄任何記錄即可迅速...
MySQL索引分析和優化 什麼是索引?
mysql索引分析和優化 什麼是索引?索引用來快速地尋找那些具有特定值的記錄,所有mysql索引都以b 樹的形式儲存。如果沒有索引,執行查詢時mysql必須從第乙個記錄開始掃瞄整個表的所有記錄,直至找到符合要求的記錄。表裡面的記錄數量越多,這個操作的代價就越高。如果作為搜尋條件的列上已經建立了索引,...
MySQL索引優化分析
1.通過訂單號查詢某個訂單,用唯一索引 資料量幾百萬以上 2.order by 排序時,後面欄位加 強制指定索引 select from orderforce index idx ordere order by order level,input date 哪些情況需要建索引 1 主鍵,唯一索引 2...