mysql資料庫中的索引

2021-07-11 21:09:20 字數 4885 閱讀 9389

一、什麼是索引? 

索引用來快速地尋找那些具有特定值的記錄,所有mysql索引都以b-樹的形式儲存。如果沒有索引,執行查詢時mysql必須從第乙個記錄開始掃瞄整個表的所有記錄,直至找到符合要求的記錄。表裡面的記錄數量越多,這個操作的代價就越高。如果作為搜尋條件的列上已經建立了索引,mysql無需掃瞄任何記錄即可迅速得到目標記錄所在的位置。如果表有1000個記錄,通過索引查詢記錄至少要比順序掃瞄記錄快100倍。 

假設我們建立了乙個名為people的表: 

create table people ( peopleid smallint not null, 

name char(50) not null );

然後,我們完全隨機把1000個不同name值插入到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處理的記錄數量越少,則它完成任務的速度就越快。 

二、索引的型別   www.2cto.com  

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) not null, lastname char(50) not null, 

age smallint not null,

townid smallint not null, primary key (peopleid) );

下面是我們插入到這個people表的資料: 

這個資料片段中有四個名字為「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); 

由於索引檔案以b-樹格式儲存,mysql能夠立即轉到合適的firstname,然後再轉到合適的lastname,最後轉到合適的age。在沒有掃瞄資料檔案任何乙個記錄的情況下,mysql就正確地找出了搜尋的目標記錄! 

四、最左字首 

多列索引還有另外乙個優點,它通過稱為最左字首(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';

五、選擇索引列 

在效能優化過程中,選擇在哪些列上建立索引是最重要的步驟之一。可以考慮使用索引的主要有兩種型別的列:在where子句中出現的列,在join子句中出現的列。請看下面這個查詢: 

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';」這個查詢不會使用索引

資料庫mysql索引 資料庫 mysql索引

mysql 索引 mysql索引的建立對於mysql的高效執行是很重要的,索引可以大大提高mysql的檢索速度。打個比方,如果合理的設計且使用索引的mysql是一輛蘭博基尼的話,那麼沒有設計和使用索引的mysql就是乙個人力三輪車。索引分單列索引和組合索引。單列索引,即乙個索引只包含單個列,乙個表可...

MySQL資料庫中的索引

在mysql中索引 索引也是一張表,該錶儲存了主鍵與索引字段,並指向實體表的記錄。建立索引的原則 1 查詢頻率高,資料量大表 2查詢條件 where 後面的字段 3 使用唯一索引,區分度高 4 使用短的字段 5 使用最左字首 btree b 樹 innodb預設引擎使用的索引結構 hash r tr...

MySQL資料庫中的索引

建表時建立 create table mytable name varchar 32 index index mytable name name 建表後,直接建立索引 create index index mytable name on mytable name 修改表結構 alter table ...