MySQL索引分析和優化

2021-05-02 14:08:40 字數 3399 閱讀 2667

索引

索引用來快速地尋找那些具備特定值的記錄,任何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) 

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就正確地找出了搜尋的目標記錄!

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

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...