MYSQL索引詳解

2021-08-20 14:58:32 字數 4576 閱讀 2239

本文優化並補充了大佬的文章:

索引的定義(索引別稱index,key,鍵)

在關聯式資料庫中,索引是對錶中一列或多列的值進行排序的一種儲存結構,它是表中一列或多列的值的集合,而且其中包含了對應表中記錄的引用指標

。索引的作用相當於圖書的目錄,可以根據目錄中的頁碼快

速找到所需的內容。

要注意的是,索引也是表的組成部分,建立太多的索引將會影響更新和插入的速度,因為它需要同樣更新每個索引檔案。對於乙個經常需要更新和插入的**,就沒有必要為乙個很少使用的where字句單獨建立索引了,對於比較小的表,排序的開銷不會很大,也沒有必要建立索引。

舉個例子:首先,先假設有一張表,表有10w個記錄,其中有一條記錄我們已知a='1',如果想要拿到對應記錄的話,需要的sql語句是 select * from *** where a='1'.

一般情況下,對於查詢語句,在沒有建立索引的時候,mysql會進行全表掃瞄,而且不掃瞄完10w個記錄不會停止,如果我在nickname上建立索引,那麼mysql相當於只掃瞄nickname這一列即可,而且因為這一列已排好序,找到對應結果或結果集可以直接返回。

mysql的索引分為單列索引(全文索引,主鍵索引,唯一索引,普通索引)和組合索引。

單列索引:乙個索引只包含乙個列,乙個表可以有多個單列索引。

組合索引:乙個組合索引包含兩個或兩個以上的列,

(一)索引的建立

1.單列索引

1-1)    普通索引(這個是最基本的索引)

建表時:index indexname(`欄位名`(length)) 

建表後:create index indexname on `tablename`(`欄位名`(length)) 

或alter table tablename add index indexname(`欄位名`(length)

注意:如果字段資料是char,varchar型別,可以指定length,其值小於欄位的實際長度,如果是blob和text型別就必須指定length。

這個length的用處是什麼?

有時候需要在長文字欄位上建立索引,但這種索引會增加索引的儲存空間以及降低索引的效率,這時就可以用到length,建立索引時用到length的索引,我們叫做字首索引,字首索引是選擇字段資料的前n個字元作為索引,這樣可以大大節約索引空間,從而提高索引效率。

此處展示的語句用於建立乙個索引,索引使用字段資料的前10個字元。

create index part_of_name on customer (name(10));

使用字段資料的一部分建立索引可以使索引檔案大大減小,從而節省了大量的磁碟空間,有可能提高insert操作的速度。

字首索引是一種能使索引更小,更快的有效辦法,但是mysql無法使用字首索引做order by 和 group by以及使用字首索引做覆蓋掃瞄。

這裡又引出了乙個新概念,覆蓋掃瞄!

如果乙個索引(如:組合索引)中包含所有要查詢的字段的值,那麼就稱之為覆蓋索引,如:

select user_name, city, age from user_test where user_name = 'feinik' and age > 25;

因為要查詢的字段(user_name, city, age)都包含在組合索引的索引列中,所以就使用了覆蓋索引查詢,檢視是否使用了覆蓋索引可以通過執行計畫中的extra中的值為using index則證明使用了覆蓋索引,覆蓋索引可以極大的提高訪問效能。

1-2)    唯一索引,要求字段所有的值是唯一的,這一點和主鍵索引一樣,但是允許有空值。

建表時:unique index indexname(`欄位名`(length)) 

建表後:create unique  index indexname on `tablename`(`欄位名`(length)) 

或alter table tablename add unique  index indexname(`欄位名`(length))

1-3)    主鍵索引,不允許有空值

一般在建表的時候自動建立,主鍵一般會設為 int 而且是 auto_increment自增型別的

1-4)全文索引

假設欄位的資料型別是長文字,文字欄位上(text等)建立了普通索引,我們需要查詢關鍵字的話,那麼其條件只能是where column like '%***x%' ,但是,這樣做就會讓索引失效,這時就需要全文索引了。

建表時:fulltext index indexname(`欄位名`(length)) 

建表後:create fulltext  index indexname on `tablename`(`欄位名`(length)) 

或alter table tablename add fulltext  index indexname(`欄位名`(length))

使用:select * from tablename

where match(column1, column2) against(『***′, 『sss′, 『ddd′)

這條命令將把column1和column2欄位裡有***、sss和ddd的資料記錄全部查詢出來。

下面我們來舉個例子:

假設有乙個書籍表,結構如下,文章內容欄位的資料型別是text

文章id

文章標題

文章內容

1超級塞亞人

我是超級塞亞人我喜歡吃蘋果,我不是**的人,也不是地球人

2**大國

我大**威武,我大**13億人,我大**

3我喜歡游泳

游泳有很多好方法

4動畫片

我兒子喜歡看動畫片,尤其是七龍珠,因為裡面有塞亞人,而且塞亞人喜歡吃蘋果,他們不是地球人5運動

我喜歡運動,喜歡跑步,喜歡游泳,喜歡健身,喜歡xxoo6**

我是乙個二戰的老兵,這是我的回憶錄,我最幸福的時光就是在**吃著蘋果**

7..........

..........

8..........

..........

9..........

..........

我們在文章內容欄位上建立全文索引,下面是索引檔案

文章id(引用指標)

塞亞人1,4

蘋果1,4,6

**1,2,6

地球1,4

游泳3,5

七龍珠4

喜歡1,4,5,6

那麼當我想搜尋  「塞亞人」的時候,這個索引檔案直接告訴我在文章id為1和4的文章裡有這個詞。

coreseek=sphinx+mmesg 這個程式就可以解決這個問題的啦。

sphinx就是索引程式。

mmseg就是分詞程式。

國內有人修改了sphinx原始碼,內建和mmseg配合,整合到一起就是coreseek啦(中文版sphinx)!

2.組合索引

假設欄位a,b都有索引,我們的查詢條件是a=1,b=2查詢過程是mysql會先挑選出符合a=1的結果集,再在這些結果集中挑選b=2的結果集,但是mysql並不會在查詢a,b時都用到索引,只會用其中乙個,這和我們的預期不一樣,所以,我們要使用組合索引

建表時:index indexname(`欄位名`(length),`欄位名`(length),........) 

建表後:create index indexname on `tablename`(`欄位名`(length),`欄位名`(length),........) 

或alter table tablename add index indexname(`欄位名`(length),`欄位名`(length),........) 

(二)索引的刪除

dorp index indexname on `tablename`

(三)索引失效的情況 

1.如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什麼盡量少用or的原因)

要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引

2.使用查詢的時候遵循mysql組合索引的"最左字首"規則,假設現在有組合索引(a,b,c),查詢語句就只能是a=1或a=1

and b=1或a=1 and b=1 and c=1。這裡有兩點需要注意①a=1 and b=1和b=1 and a=1一樣,沒有區別,都會使用索引②組合索引(a,b,c)的最左字首是a;組合索引(c,b,a)的最左字首是c,最左字首和表字段順序無關

在組合索引中,如果where查詢條件中某個列使用了範圍查詢(不管%在哪),則其右邊的所有列都無法使用索引優化查詢

3.like查詢以%開頭

4.如果列型別是字串,那一定要在條件中將資料使用引號引用起來,否則不使用索引

5.如果mysql估計使用全表掃瞄要比使用索引快,則不使用索引

6.索引列不能是表示式的一部分,也不能作為函式的引數,否則無法使用索引查詢。下面是例子:

1

select*from

user_testwhere

user_name = concat(user_name,'fei');



MySQL聚集索引詳解 mysql 索引詳解

直接起飛 1.什麼是索引?索引是幫助mysql高效獲取資料的排好序的資料結構。2.索引的資料結構?為什麼選這種結構?假設我們現在這裡有一張表 以下情況都是innodb儲存引擎 idnumber 如果mysql沒有索引這種結構,那麼我們如果查詢number為51的這行記錄,那麼mysql就要從上往下掃...

MySQL聚集索引詳解 mysql索引詳解

資料結構分,有b tree索引 b tree 雜湊索引 r tree索引等。按資料塊的順序和索引節點的邏輯順序是否一致可以分為聚集索引和非聚集索引。聚集索引由於物理塊連續,在範圍掃瞄的時候可以減少磁頭尋道時間,因而比非聚集索引高效。幾種索引型別的選擇 primary 主鍵索引。unique 唯一索引...

mysql 索引定義 MySQL 索引詳解

普通索引 唯一索引和主索引 1.普通索引 普通索引 由關鍵字key或index定義的索引 的唯一任務是加快對資料的訪問速度。因此,應該只為那些最經常出現在查詢條件 where column 或排序條件 order by column 中的資料列建立索引。只要有可能,就應該選擇乙個資料最整齊 最緊湊的...