當前位置:首頁 » 數據倉庫 » mysql資料庫索引類型
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

mysql資料庫索引類型

發布時間: 2023-06-08 23:12:14

『壹』 mysql索引使用的是Btree還是B+tree為什麼

結合MySQL中Innodb存儲引擎索引結構來看的話……
教科書上的B+Tree是一個簡化了的,方便於研究和教學的B+Tree。然而在資料庫實現時,為了更好的性能或者降低實現的難度,都會在細節上進行一定的變化。下面以InnoDB為例,來說說這些變化。
04 - Sparse Index中的數據指針
在「由淺入深理解InnoDB索引的實現(1)」中提到,Sparse Index中的每個鍵值都有一個指針指向所在的數據頁。這樣每個B+Tree都有指針指向數據頁。
如果數據頁進行了拆分或合並操作,那麼所有的B+Tree都需要修改相應的頁指針。特別是Secondary B+Tree(輔助索引對應的B+Tree), 要對很多個不連續的頁進行修改。同時也需要對這些頁加鎖,這會降低並發性。為了降低難度和增加更新(分裂和合並B+Tree節點)的性能,InnoDB 將 Secondary B+Tree中的指針替換成了主鍵的鍵值。
這樣就去除了Secondary B+Tree對數據頁的依賴,而數據就變成了Clustered B+Tree(簇索引對應的B+Tree)獨占的了。對數據頁的拆分及合並操作,僅影響Clustered B+Tree. 因此InnoDB的數據文件中存儲的實際上就是多個孤立B+Tree。
一個有趣的問題: 當用戶顯式的把主鍵定義到了二級索引中時,還需要額外的主鍵來做二級索引的數據嗎(即存儲2份主鍵)? 很顯然是不需要的。InnoDB在創建二級索引的時候,會判斷主鍵的欄位是否已經被包含在了要創建的索引中.
接下來看一下數據操作在B+Tree上的基本實現。
- 用主鍵查詢
直接在Clustered B+Tree上查詢。
- 用輔助索引查詢
A. 在Secondary B+Tree上查詢到主鍵。
B. 用主鍵在Clustered B+Tree上查詢到數據。
可以看出,在使用主鍵值替換頁指針後,輔助索引的查詢效率降低了。
A. 如果能用主鍵查詢,盡量使用主鍵來查詢數據。
B. 但是由於Clustered B+Tree包含了完整的數據,遍歷的效率比 Secondary B+Tree的效率低。如果遍歷操作不涉及到二級索引和主鍵以外的數據,則盡量使用二級索引進行遍歷。

- INSERT
A. 在Clustered B+Tree上插入一條記錄
B. 在所有其他Secondary B+Tree上插入一條記錄(僅包含索引欄位和主鍵)
- DELETE
A. 在Clustered B+Tree上刪除一條記錄。
B. 在所有Secondary B+Tree上刪除二級索引的記錄。
- UPDATE 非鍵列
A. 在Clustered B+Tree上更新數據。
- UPDATE 主鍵列
A. 在Clustered B+Tree刪除原有的記錄(只是標記為DELETED,並不真正刪除)。
B. 在Clustered B+Tree插入一條新的記錄。
C. 在每一個Secondary B+Tree上刪除原有的記錄。(有疑問,看下一節。)
D. 在每一個Secondary B+Tree上插入一個條新的記錄。
- UPDATE 輔助索引的鍵值
A. 在Clustered B+Tree上更新數據。
B. 在每一個Secondary B+Tree上刪除原有的記錄。
C. 在每一個Secondary B+Tree上插入一條新的記錄。
更新鍵列時,需要更新多個頁,效率比較低。
A. 盡量不用對主鍵列進行UPDATE操作。
B. 更新很多時,盡量少建索引。
05 – 非唯一鍵索引
教科書上的B+Tree操作,通常都假設」鍵值是唯一的「。但是在實際的應用中Secondary Index是允許鍵值重復的。在極端的情況下,所有的鍵值都一樣,該如何來處理呢?InnoDB 的 Secondary B+Tree中,主鍵也是此二級鍵的一部分。 Secondary Key = 用戶定義的KEY + 主鍵。
注意主鍵不僅做為數據出現在葉子節點,同時也作為鍵的一部分出現非葉子節點。對於非唯一鍵來說,因為主鍵是唯一的,Secondary Key也是唯一的。當然,在插入數據時,還是會根據用戶定義的Key,來判斷唯一性。按理說,如果輔助索引是唯一的(並且所有欄位不能為空),就不需要這樣做。可是,InnoDB對所有的Secondary B+Tree都這樣創建。
還沒弄明白有什麼特殊的用途?有知道的朋友可以幫忙解答一下。
也許是為了降低代碼的復雜性,這是我想到的唯一理由。
弄清楚了,即便是非空唯一鍵,在二級索引的B+Tree中也可能重復,因此必須要將主鍵加入到非葉子節點。
06 – <Key, Pointer>對

標準的B+Tree的每個節點有K個鍵值和K+1個指針,指向K+1個子節點。
而在「由淺入深理解索引的實現(1)」中圖. 9的B+Tree上,每個節點有K個鍵值和K個指針。InnoDB的B+Tree也是如此。
這樣做的好處在於,鍵值和指針一一對應。我們可以將一個<Key,Pointer>對看作一條記錄。這樣就可以用數據塊的存儲格式來存儲索引塊。因為不需要為索引塊定義單獨的存儲格式,就降低了實現的難度。
- 插入最小值
當考慮在變形後的B+Tree上進行INSERT操作時,發現了一個有趣的問題。如果插入的數據的健值比B+Tree的最小鍵值小時,就無法定位到一個適當的數據塊上去(<Key,Pointer>中的Key代表了子節點上的鍵值是>=Key的)。例如,在圖.5的B+Tree中插入鍵值為0的數據時,無法定位到任何節點。在標準的B+Tree上,這樣的鍵值會被定位到最左側的節點上去。這個做法,對於圖.5中的B+Tree也是合理的。Innodb的做法是,將每一層(葉子層除外)的最左側節點的第一條記錄標記為最小記錄(MIN_REC).在進行定位操作時,任何鍵值都比標記為MIN_REC的鍵值大。因此0會被插入到最左側的記錄節點上。

07 – 順序插入數據
標準的B-Tree分裂時,將一半的鍵值和數據移動到新的節點上去。原有節點和新節點都保留一半的空間,用於以後的插入操作。當按照鍵值的順序插入數據時,左側的節點不可能再有新的數據插入。因此,會浪費約一半的存儲空間。
解決這個問題的基本思路是:分裂順序插入的B-Tree時,將原有的數據都保留在原有的節點上。創建一個新的節點,用來存儲新的數據。順序插入時的分裂過程.
以上是以B-Tree為例,B+Tree的分裂過程類似。InnoDB的實現以這個思路為基礎,不過要復雜一些。因為順序插入是有方向性的,可能是從小到大,也可能是從大到小的插入數據。所以要區分不同的情況。如果要了解細節,可參考以下函數的代碼。

btr_page_split_and_insert();
btr_page_get_split_rec_to_right();
btr_page_get_split_rec_to_right();
InnoDB的代碼太復雜了,有時候也不敢肯定自己的理解是對的。因此寫了一個小腳本,來列印InnoDB數據文件中B+Tree。這樣可以直觀的來觀察B+Tree的結構,驗證自己的理解是否正確。

『貳』 mysql索引類型解釋

索引分單列索引和組合索引。單列索引,即一個索引只包含單個列,一個表可以有多個單列索引,但這不是組合索引。組合索引,即一個索包含多個列。
MySQL索引類型包括:
(1)普通索引
這是最基本的索引,它沒有任何限制。它有以下幾種創建方式:
◆創建索引
CREATE INDEX indexName ON mytable(username(length));
如果是 CHAR,VARCHAR類型,length可以小於欄位實際長度;如果是BLOB和TEXT類型,必須指定 length,下同。
◆修改表結構
ALTER mytable ADD INDEX [indexName] ON (username(length))
◆ 創建表的時候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX [indexName] (username(length)) );
刪除索引的語法:
DROP INDEX [indexName] ON mytable;
(2)唯一索引
它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種創建方式:
◆創建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length))
◆修改表結構
ALTER mytable ADD UNIQUE [indexName] ON (username(length))
◆創建表的時候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE [indexName] (username(length)) );
(3)主鍵索引
它是一種特殊的唯一索引,不允許有空值。一般是在建表的時候同時創建主鍵索引:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, PRIMARY KEY(ID) );
當然也可以用 ALTER 命令。記住:一個表只能有一個主鍵。
(4)組合索引
為了形象地對比單列索引和組合索引,為表添加多個欄位:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, city VARCHAR(50) NOT NULL, age INT NOT NULL );
為了進一步榨取MySQL的效率,就要考慮建立組合索引。就是將 name, city, age建到一個索引里:
ALTER TABLE mytable ADD INDEX name_city_age (name(10),city,age);
建表時,usernname長度為 16,這里用 10。這是因為一般情況下名字的長度不會超過10,這樣會加速索引查詢速度,還會減少索引文件的大小,提高INSERT的更新速度。
如果分別在 usernname,city,age上建立單列索引,讓該表有3個單列索引,查詢時和上述的組合索引效率也會大不一樣,遠遠低於我們的組合索引。雖然此時有了三個索引,但MySQL只能用到其中的那個它認為似乎是最有效率的單列索引。
建立這樣的組合索引,其實是相當於分別建立了下面三組組合索引:
usernname,city,age usernname,city usernname
為什麼沒有 city,age這樣的組合索引呢?這是因為MySQL組合索引「最左前綴」的結果。簡單的理解就是只從最左面的開始組合。並不是只要包含這三列的查詢都會用到該組合索引,下面的幾個SQL就會用到這個組合索引:
SELECT * FROM mytable WHREE username="admin" AND city="鄭州" SELECT * FROM mytable WHREE username="admin"
而下面幾個則不會用到:
SELECT * FROM mytable WHREE age=20 AND city="鄭州" SELECT * FROM mytable WHREE city="鄭州"
(5)建立索引的時機
到這里我們已經學會了建立索引,那麼我們需要在什麼情況下建立索引呢?一般來說,在WHERE和JOIN中出現的列需要建立索引,但也不完全如此,因為MySQL只對<,<=,=,>,>=,BETWEEN,IN,以及某些時候的LIKE才會使用索引。例如:
SELECT t.Name FROM mytable t LEFT JOIN mytable m ON t.Name=m.username WHERE m.age=20 AND m.city='鄭州'
此時就需要對city和age建立索引,由於mytable表的 userame也出現在了JOIN子句中,也有對它建立索引的必要。
剛才提到只有某些時候的LIKE才需建立索引。因為在以通配符%和_開頭作查詢時,MySQL不會使用索引。例如下句會使用索引:
SELECT * FROM mytable WHERE username like'admin%'
而下句就不會使用:
SELECT * FROM mytable WHEREt Name like'%admin'
因此,在使用LIKE時應注意以上的區別。
(6)索引的不足之處
上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:
◆雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進行 INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件。
◆建立索引會佔用磁碟空間的索引文件。一般情況這個問題不太嚴重,但如果你在一個大表上創建了多種組合索引,索引文件的會膨脹很快。
索引只是提高效率的一個因素,如果你的 MySQL有大數據量的表,就需要花時間研究建立最優秀的索引,或優化查詢語句。
(7)使用索引的注意事項
使用索引時,有以下一些技巧和注意事項:
◆索引不會包含有NULL值的列
只要列中包含有NULL值都將不會被包含在索引中,復合索引中只要有一列含有 NULL值,那麼這一列對於此復合索引就是無效的。所以我們在資料庫設計時不要讓欄位的默認值為NULL。
◆使用短索引
對串列進行索引,如果可能應該指定一個前綴長度。例如,如果有一個CHAR(255)的列,如果在前10個或20個字元內,多數值是惟一的,那麼就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁碟空間和I/O操作。
◆索引列排序
MySQL查詢只使用一個索引,因此如果 where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。因此資料庫默認排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個列的排序,如果需要最好給這些列創建復合索引。
◆like語句操作
一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like 「%aaa%」 不會使用索引而like 「aaa%」可以使用索引。
◆不要在列上進行運算
select * from users where YEAR(adddate)<2007;
將在每個行上進行運算,這將導致索引失效而進行全表掃描,因此我們可以改成
select * from users where adddate<『2007-01-01』;
◆不使用NOT IN和<>操作
以上,就對其中MySQL索引類型進行了介紹。
轉自:http://www.zbite.com/?action-viewthread-tid-33491

『叄』 mysql索引採用什麼數據結構

文就是對這兩種數據結構做簡單的介紹。
1. B-Tree
B-Tree不是「B減樹」,而是「B樹」。
這里參考了嚴蔚敏《數據結構》對B-Tree的定義:
一棵m階的B-Tree,或者為空樹,或者滿足下列特性:
1.樹中每個結點至多有m棵子樹;
2.若根結點不是葉子結點,則至少有兩棵子樹;
3.除根節點之外的所有非終端結點至少有[m/2]棵子樹;
4.所有非終端結點中包含下列信息數據:
(n,A0,K1,A1,K2,A2……Kn,An)
其中,n為關鍵字的數目,K(i)為關鍵字,且K(i) < K(i+1), Ai為指向子樹根結點的指針,且指針A(i-1)所指子樹中所有結點的關鍵字均小於Ki,Ai所指子樹中所有結點的關鍵字均大於Ki;
5.所有葉子結點都出現在同一層次上;
下面通過一個例子解釋一下B-Tree的查找過程。

這是一棵4階的B-Tree,深度為4。
假如在該圖中查找關鍵字47,首先從根結點開始,根據根結點指針t找到*a結點,因為47大於 *a 結點的關鍵字35,所以會去A1指針指向的 *c結點繼續尋找,因為 *c的關鍵字 43 < 要查找的47 < *c結點的關鍵字78,所以去 *c結點A1指針指向的 *g結點去尋找,結果在 *g結點中找到了關鍵字47,查找成功。
2. B+Tree
不同的存儲引擎可能使用不同的數據結構存儲,InnoDB使用的是B+Tree;那什麼是B+Tree呢?
B+Tree是應文件系統所需而出的一種B-Tree的變型樹,一棵m階的B+樹和m階的B-樹的差異在於:
1.有n棵子樹的結點中含有n個關鍵字;
2.所有的葉子結點中包含了全部關鍵字的信息,及指向含這些關鍵字的記錄的指針,且葉子結點本身依關鍵字的大小自小而大順序鏈接;
3.所有的非終端結點可以看成是索引部分,結點中僅含有其子樹(根結點)中的最大(或最小)關鍵字;
還是通過一個例子來說明。

這個例子中,所有非終端結點僅含有子樹中最大的關鍵字。
因為葉子節點本身依據關鍵字的大小自小而大順序鏈接,所以可以從最小關鍵字起順序查找。也可以從根結點開始,進行隨機查找。
在B+樹中隨機差找和在B-樹中類似,以上圖為例。假設要查找關鍵字51,現在根節點中比較,發現51<59,因為這里使用的是非終端結點的關鍵字是子樹中最大的關鍵字,所以進入最大值為59的子結點(15\44\59)中查找,同理,因為44<51<59,所以進入P3指向的結點(51\59)中查找,然後命中關鍵字51,因為此結點(51\59)是葉子結點,所以查找終止,該結點包含指向數據的指針。

3.索引如何在B+Tree中組織數據存儲
假設有如下表:

對於表中的每一行數據,索引中包含了last_name、first_name和dob列的值,下圖展示索引是如何組織數據存儲的:

索引對多個值進行排序的依據是定義索引時列的順序。
(Allen Cuba 1960-01-01)結點左側的指針指向[?,Allen Cuba 1960-01-01)的葉子頁,(Allen Cuba 1960-01-01)和(Astaire,Angelina,1980-03-04)之間的指針指向[Allen Cuba 1960-01-01,Astaire Angelina 1980-03-04)的葉子頁,以此類推。總之,每個指針指向的結點中的最小值就是該指針左側的的值。
這種存儲結構也說明了在定義多個列組成的多列索引中,為什麼需要把重復率最低的列放到最左側,因為這會減少比較的次數,查找起來更加高效。
4.索引為什麼選用B樹這種數據結構?
因為使用B樹查找時,所用的磁碟IO操作次數比平衡二叉樹更少,效率也更高。
為什麼使用B樹查找所用的磁碟IO操作次數比平衡二叉樹更少?
大規模數據存儲中,樹節點存儲的元素數量是有限的(如果元素數量非常多的話,查找就退化成節點內部的線性查找了),這樣導致二叉查找樹結構由於樹的高度過大而造成磁碟I/O讀寫過於頻繁,進而導致查詢效率低下。那麼我們就需要減少樹的高度以提高查找效率。而平衡多路查找樹結構B樹就滿足這樣的要求。B樹的各種操作能使B樹保持較低的高度,從而達到有效減少磁碟IO操作次數。

『肆』 MySQL資料庫的四類索引

index ---- 普通索引,數據可以重復,沒有任何限制。
unique ---- 唯一索引,要求索引列的值必須唯一,但允許有空值;如果是組合索引,那麼列值的組合必須唯一。

primary key ---- 主鍵索引,是一種特殊的唯一索引,一個表只能有一個主鍵,不允許有空值,一般是在創建表的同時創建主鍵索引。

組合索引 ---- 在多個欄位上創建的索引,只有在查詢條件中使用了創建索引時的第一個欄位,索引才會被使用。

fulltext ---- 全文索引,是對於大表的文本域:char,varchar,text列才能創建全文索引,主要用於查找文本中的關鍵字,並不是直接與索引中的值進行比較。fulltext更像是一個搜索引擎,配合match against操作使用,而不是一般的where語句加like。

注:全文索引目前只有MyISAM存儲引擎支持全文索引,InnoDB引擎5.6以下版本還不支持全文索引

所有存儲引擎對每個表至少支持16個索引,總索引長度至少為256位元組,索引有兩種存儲類型,包括B型樹索引和哈希索引。

索引可以提高查詢的速度,但是創建和維護索引需要耗費時間,同時也會影響插入的速度,如果需要插入大量的數據時,最好是先刪除索引,插入數據後再建立索引。

『伍』 MYSQL資料庫索引類型都有哪些

聚集索引:也稱 Clustered Index。是指關系表記錄的物理順序與索引的邏輯順序相同。由於一張表只能按照一種物理順序存放,一張表最多也只能存在一個聚集索引。與非聚集索引相比,聚集索引有著更快的檢索速度。
MySQL 里只有 INNODB 表支持聚集索引,INNODB 表數據本身就是聚集索引,也就是常說 IOT,索引組織表。非葉子節點按照主鍵順序存放,葉子節點存放主鍵以及對應的行記錄。所以對 INNODB 表進行全表順序掃描會非常快。
非聚集索引:也叫 Secondary Index。指的是非葉子節點按照索引的鍵值順序存放,葉子節點存放索引鍵值以及對應的主鍵鍵值。MySQL 里除了 INNODB 表主鍵外,其他的都是二級索引。MYISAM,memory 等引擎的表索引都是非聚集索引。簡單點說,就是索引與行數據分開存儲。一張表可以有多個二級索引。

『陸』 如何正確合理的建立MYSQL資料庫索引

如何正確合理的建立MYSQL資料庫索引

索引是快速搜索的關鍵。MySQL索引的建立對於MySQL的高效運行是很重要的。下面介紹幾種常見的MySQL索引類型。

在資料庫表中,對欄位建立索引可以大大提高查詢速度。假如我們創建了一個 mytable表:

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL
); 我們隨機向裡面插入了10000條記錄,其中有一條:5555, admin。

在查找username="admin"的記錄 SELECT * FROM mytable WHERE
username='admin';時,如果在username上已經建立了索引,MySQL無須任何掃描,即准確可找到該記錄。相反,MySQL會掃描所有記錄,即要查詢10000條記錄。

索引分單列索引和組合索引。單列索引,即一個索引只包含單個列,一個表可以有多個單列索引,但這不是組合索引。組合索引,即一個索包含多個列。

MySQL索引類型包括:

(1)普通索引

這是最基本的索引,它沒有任何限制。它有以下幾種創建方式:

◆創建索引

CREATE INDEX indexName ON mytable(username(length));
如果是CHAR,VARCHAR類型,length可以小於欄位實際長度;如果是BLOB和TEXT類型,必須指定 length,下同。

◆修改表結構

ALTER mytable ADD INDEX [indexName] ON (username(length))

◆創建表的時候直接指定

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL,
INDEX [indexName] (username(length)) ); 刪除索引的語法:

DROP INDEX [indexName] ON mytable;

(2)唯一索引

它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種創建方式:

◆創建索引

CREATE UNIQUE INDEX indexName ON mytable(username(length))

◆修改表結構

ALTER mytable ADD UNIQUE [indexName] ON (username(length))

◆創建表的時候直接指定

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL,
UNIQUE [indexName] (username(length)) );

(3)主鍵索引

它是一種特殊的唯一索引,不允許有空值。一般是在建表的時候同時創建主鍵索引:

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL,
PRIMARY KEY(ID) ); 當然也可以用 ALTER 命令。記住:一個表只能有一個主鍵。

(4)組合索引

為了形象地對比單列索引和組合索引,為表添加多個欄位:

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL,
city VARCHAR(50) NOT NULL, age INT NOT NULL );
為了進一步榨取MySQL的效率,就要考慮建立組合索引。就是將 name, city, age建到一個索引里:

ALTER TABLE mytable ADD INDEX name_city_age (name(10),city,age);
建表時,usernname長度為 16,這里用
10。這是因為一般情況下名字的長度不會超過10,這樣會加速索引查詢速度,還會減少索引文件的大小,提高INSERT的更新速度。

如果分別在
usernname,city,age上建立單列索引,讓該表有3個單列索引,查詢時和上述的組合索引效率也會大不一樣,遠遠低於我們的組合索引。雖然此時有了三個索引,但MySQL只能用到其中的那個它認為似乎是最有效率的單列索引。

建立這樣的組合索引,其實是相當於分別建立了下面三組組合索引:

usernname,city,age usernname,city usernname 為什麼沒有
city,age這樣的組合索引呢?這是因為MySQL組合索引「最左前綴」的結果。簡單的理解就是只從最左面的開始組合。並不是只要包含這三列的查詢都會用到該組合索引,下面的幾個SQL就會用到這個組合索引:

SELECT * FROM mytable WHREE username="admin" AND city="鄭州" SELECT * FROM
mytable WHREE username="admin" 而下面幾個則不會用到:

SELECT * FROM mytable WHREE age=20 AND city="鄭州" SELECT * FROM mytable WHREE
city="鄭州"

(5)建立索引的時機

到這里我們已經學會了建立索引,那麼我們需要在什麼情況下建立索引呢?一般來說,在WHERE和JOIN中出現的列需要建立索引,但也不完全如此,因為MySQL只對<,<=,=,>,>=,BETWEEN,IN,以及某些時候的LIKE才會使用索引。例如:

SELECT t.Name FROM mytable t LEFT JOIN mytable m ON t.Name=m.username
WHERE m.age=20 AND m.city='鄭州'
此時就需要對city和age建立索引,由於mytable表的userame也出現在了JOIN子句中,也有對它建立索引的必要。

剛才提到只有某些時候的LIKE才需建立索引。因為在以通配符%和_開頭作查詢時,MySQL不會使用索引。例如下句會使用索引:

SELECT * FROM mytable WHERE username like'admin%' 而下句就不會使用:

SELECT * FROM mytable WHEREt Name like'%admin' 因此,在使用LIKE時應注意以上的區別。

(6)索引的不足之處

上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:

◆雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件。

◆建立索引會佔用磁碟空間的索引文件。一般情況這個問題不太嚴重,但如果你在一個大表上創建了多種組合索引,索引文件的會膨脹很快。

索引只是提高效率的一個因素,如果你的MySQL有大數據量的表,就需要花時間研究建立最優秀的索引,或優化查詢語句。

(7)使用索引的注意事項

使用索引時,有以下一些技巧和注意事項:

◆索引不會包含有NULL值的列

只要列中包含有NULL值都將不會被包含在索引中,復合索引中只要有一列含有NULL值,那麼這一列對於此復合索引就是無效的。所以我們在資料庫設計時不要讓欄位的默認值為NULL。

◆使用短索引

對串列進行索引,如果可能應該指定一個前綴長度。例如,如果有一個CHAR(255)的列,如果在前10個或20個字元內,多數值是惟一的,那麼就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁碟空間和I/O操作。

◆索引列排序

MySQL查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那麼order
by中的列是不會使用索引的。因此資料庫默認排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個列的排序,如果需要最好給這些列創建復合索引。

◆like語句操作

一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like 「%aaa%」 不會使用索引而like
「aaa%」可以使用索引。

◆不要在列上進行運算

select * from users where YEAR(adddate)<2007;
將在每個行上進行運算,這將導致索引失效而進行全表掃描,因此我們可以改成

select * from users where adddate<『2007-01-01』;

◆不使用NOT IN和<>操作

以上,就對其中MySQL索引類型進行了介紹。

『柒』 mysql採用哪些索引,B樹索引解釋下

事實上,在MySQL資料庫中,諸多存儲引擎使用的是B+樹,即便其名字看上去是BTREE。

4.1 innodb的索引機制

先以innodb存儲引擎為例,說明innodb引擎是如何利用B+樹建立索引的

首先創建一張表:zodiac,並插入一些數據