新聞中心
在關(guān)系數(shù)據(jù)庫(kù)中,索引是一種用來(lái)提高查詢效率的數(shù)據(jù)結(jié)構(gòu)。數(shù)據(jù)庫(kù)管理系統(tǒng)會(huì)在查詢時(shí)使用索引來(lái)快速定位所需的數(shù)據(jù)。當(dāng)數(shù)據(jù)庫(kù)中數(shù)據(jù)量比較大時(shí),創(chuàng)建索引可以有效提高查詢速度,從而提高系統(tǒng)的性能。尤其在一些經(jīng)常需要查詢的列中使用索引可以讓查詢速度明顯提升。但是,索引也要合理使用,過(guò)多的創(chuàng)建索引會(huì)增加數(shù)據(jù)庫(kù)的存儲(chǔ)空間和降低數(shù)據(jù)的寫(xiě)入和更新性能。因此,在創(chuàng)建索引時(shí),需要有一定的經(jīng)驗(yàn)和技巧。

所謂復(fù)合索引,就是在一個(gè)表上創(chuàng)建多個(gè)列的索引,這些列構(gòu)成一個(gè)索引鍵。復(fù)合索引可以提高多列查詢的效率,并可以避免創(chuàng)建大量的單列索引。下面是的步驟。
之一步,確定需要?jiǎng)?chuàng)建索引的列
在確定需要?jiǎng)?chuàng)建索引的列時(shí),需要考慮以下幾個(gè)因素:
1.查詢頻率:需要查詢頻率高的列最適合創(chuàng)建索引。
2.查詢條件:需要根據(jù)查詢條件創(chuàng)建索引,可以更大限度的滿足查詢條件。
3.查詢效率:可以提高查詢效率的列最適合創(chuàng)建索引。
4.數(shù)據(jù)類型:需要選擇數(shù)據(jù)類型合適的列創(chuàng)建索引,以免索引失效。
第二步,確定索引鍵
在確定索引鍵時(shí),需要考慮以下幾個(gè)因素:
1.索引順序:需要把查詢頻率高的列放在前面,可以提高索引效率。
2.數(shù)據(jù)類型:需要保證索引鍵的數(shù)據(jù)類型一致,可以避免索引失效。
3.索引長(zhǎng)度:需要保證索引長(zhǎng)度不要超過(guò)設(shè)置的更大值,否則會(huì)導(dǎo)致索引失效。
第三步,創(chuàng)建索引
在創(chuàng)建索引時(shí),需要使用數(shù)據(jù)庫(kù)命令或者工具,具體步驟如下:
1.打開(kāi)數(shù)據(jù)庫(kù)管理系統(tǒng),在需要?jiǎng)?chuàng)建索引的表中,選擇要?jiǎng)?chuàng)建索引的列。
2.點(diǎn)擊“添加索引”按鈕,輸入索引名稱和索引鍵。
3.設(shè)置索引類型,確定索引長(zhǎng)度和是否允許重復(fù),可以根據(jù)需要選擇不同類型的索引。
4.保存索引,等待數(shù)據(jù)庫(kù)管理系統(tǒng)自動(dòng)創(chuàng)建索引。
第四步,測(cè)試索引效果
在創(chuàng)建索引后,需要對(duì)索引進(jìn)行性能測(cè)試。可以通過(guò)比較查詢相應(yīng)時(shí)間來(lái)判斷索引效果。如果查詢時(shí)間明顯變短,那么索引就是有效的。如果查詢時(shí)間變化不大,那么需要重新考慮索引的使用。
:
創(chuàng)建復(fù)合索引可以提高多列查詢效率,并可以避免創(chuàng)建大量的單列索引。但是,在創(chuàng)建索引時(shí),需要注意以下幾點(diǎn):
1.合理選擇需要?jiǎng)?chuàng)建索引的列。
2.合理選擇索引鍵。
3.選擇合適的索引類型。
4.測(cè)試索引效果。
如果能夠按照以上步驟來(lái)創(chuàng)建復(fù)合索引,就能夠更好地提高數(shù)據(jù)庫(kù)的查詢效率,提高系統(tǒng)的性能。
相關(guān)問(wèn)題拓展閱讀:
- 如何正確合理的建立MYSQL數(shù)據(jù)庫(kù)索引
如何正確合理的建立MYSQL數(shù)據(jù)庫(kù)索引
在滿足語(yǔ)句需求的情況下,盡量少的訪問(wèn)資源是數(shù)據(jù)庫(kù)設(shè)計(jì)的重要原則,這和執(zhí)行的 SQL 有直接的關(guān)系,索引問(wèn)題又是 SQL 問(wèn)題中出現(xiàn)頻率更高的,常見(jiàn)的索引問(wèn)題包括:無(wú)索引(失效)、隱式轉(zhuǎn)換。
1. SQL 執(zhí)行流程看一個(gè)問(wèn)題,在下面這個(gè)表 T 中,如果我要執(zhí)行 select * from T where k between 3 and 5; 需要執(zhí)行幾次樹(shù)的搜索操作,會(huì)掃描多少行?mysql> create table T ( -> ID int primary key, -> k int NOT NULL DEFAULT 0, -> s varchar(16) NOT NULL DEFAULT ”, -> index k(k)) -> engine=InnoDB;mysql> insert into T values(100,1, ‘a(chǎn)a’),(200,2,’bb’),\ (300,3,’cc’),(500,5,’ee’),(600,6,’ff’),(700,7,’gg’);
這分別是 ID 字段索引樹(shù)、k 字段索引樹(shù)。
這條 SQL 語(yǔ)句斗銷(xiāo)的執(zhí)行流程:
1. 在 k 索引樹(shù)上找到 k=3,獲得 ID=3002. 回表到 ID 索引樹(shù)查找 ID=300 的記錄,對(duì)應(yīng) R33. 在 k 索引樹(shù)找到下一個(gè)值 k=5,ID=5004. 再回到 ID 索引樹(shù)找到對(duì)應(yīng) ID=500 的 R4
5. 在 k 索引樹(shù)去下一個(gè)值 k=6,不符合條件,循環(huán)結(jié)束
這個(gè)過(guò)程讀取了 k 索引樹(shù)的三條記錄,回表了兩次。因?yàn)椴樵兘Y(jié)果所需要的數(shù)據(jù)只在主鍵索引上有,所以必須得回表。所以,我們?cè)撊绾瓮ㄟ^(guò)優(yōu)化索引,來(lái)避免回表呢?
2. 常見(jiàn)索引優(yōu)化2.1 覆蓋索引覆蓋索引,換言之就是索引要覆蓋我們的查詢請(qǐng)求,無(wú)需回表。
如果執(zhí)行的語(yǔ)句是 select ID from T wherek between 3 and 5;,這樣的話因?yàn)?ID 的值在 k 索引樹(shù)上,就不需要回表了。
覆蓋索引可以減少樹(shù)的搜索次數(shù),顯著提升查詢性能,是常用的性能優(yōu)化手段。
但是,維護(hù)索引是有代價(jià)的,所以在建立冗余索引來(lái)支持覆蓋索引時(shí)要權(quán)衡利弊。
2.2 最左前綴原則
B+ 樹(shù)的數(shù)據(jù)項(xiàng)是復(fù)合的數(shù)據(jù)結(jié)構(gòu),比如 (name,sex,age) 的時(shí)候,B+ 樹(shù)是按照從左到右的順序來(lái)建立搜索樹(shù)的,當(dāng) (張三,F,26) 這樣的數(shù)據(jù)來(lái)檢索的時(shí)候,B+ 樹(shù)會(huì)優(yōu)先比較 name 來(lái)確定下一步的檢索方向,如果 name 相同再依次比較 sex 和 age,最后得到檢索的數(shù)據(jù)。
# 有這樣一個(gè)空孫游表 P
mysql> create table P (id int primary key, name varchar(10) not null, sex varchar(1), age int, index tl(name,sex,age)) engine=IInnoDB;
mysql> insert into P values(1,’張凱畝三’,’F’,26),(2,’張三’,’M’,27),(3,’李四’,’F’,28),(4,’烏茲’,’F’,22),(5,’張三’,’M’,21),(6,’王五’,’M’,28);
# 下面的語(yǔ)句結(jié)果相同
mysql> select * from P where name=’張三’ and sex=’F’; ## A1
mysql> select * from P where sex=’F’ and age=26;## A2
# explain 看一下
mysql> explain select * from P where name=’張三’ and sex=’F’;
+—-++++——+-+——+++——+++
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref| rows | filtered | Extra|
+—-++++——+-+——+++——+++
| 1 | SIMPLE | P | NULL| ref | tl| tl || const,const | 1 | 100.00 | Using index |
+—-++++——+-+——+++——+++
mysql> explain select * from P where sex=’F’ and age=26;
+—-+++++-+——++——+——+++
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+++++-+——++——+——+++
| 1 | SIMPLE | P | NULL| index | NULL| tl || NULL | 6 | 16.67 | Using where; Using index |
+—-+++++-+——++——+——+++
可以清楚的看到,A1 使用 tl 索引,A2 進(jìn)行了全表掃描,雖然 A2 的兩個(gè)條件都在 tl 索引中出現(xiàn),但是沒(méi)有使用到 name 列,不符合最左前綴原則,無(wú)法使用索引。所以在建立聯(lián)合索引的時(shí)候,如何安排索引內(nèi)的字段排序是關(guān)鍵。評(píng)估標(biāo)準(zhǔn)是索引的復(fù)用能力,因?yàn)橹С肿钭笄熬Y,所以當(dāng)建立(a,b)這個(gè)聯(lián)合索引之后,就不需要給 a 單獨(dú)建立索引。原則上,如果通過(guò)調(diào)整順序,可以少維護(hù)一個(gè)索引,那么這個(gè)順序往往就是需要優(yōu)先考慮采用的。上面這個(gè)例子中,如果查詢條件里只有 b,就是沒(méi)法利用(a,b)這個(gè)聯(lián)合索引的,這時(shí)候就不得不維護(hù)另一個(gè)索引,也就是說(shuō)要同時(shí)維護(hù)(a,b)、(b)兩個(gè)索引。這樣的話,就需要考慮空間占用了,比如,name 和 age 的聯(lián)合索引,name 字段比 age 字段占用空間大,所以創(chuàng)建(name,age)聯(lián)合索引和(age)索引占用空間是要小于(age,name)、(name)索引的。
2.3 索引下推
以人員表的聯(lián)合索引(name, age)為例。如果現(xiàn)在有一個(gè)需求:檢索出表中“名字之一個(gè)字是張,而且年齡是26歲的所有男性”。那么,SQL 語(yǔ)句是這么寫(xiě)的mysql> select * from tuser where name like ‘張%’ and age=26 and sex=M;
通過(guò)最左前綴索引規(guī)則,會(huì)找到 ID1,然后需要判斷其他條件是否滿足在 MySQL 5.6 之前,只能從 ID1 開(kāi)始一個(gè)個(gè)回表。到主鍵索引上找出數(shù)據(jù)行,再對(duì)比字段值。而 MySQL 5.6 引入的索引下推優(yōu)化(index condition pushdown),可以在索引遍歷過(guò)程中,對(duì)索引中包含的字段先做判斷,直接過(guò)濾掉不滿足條件的記錄,減少回表次數(shù)。這樣,減少了回表次數(shù)和之后再次過(guò)濾的工作量,明顯提高檢索速度。
2.4 隱式類型轉(zhuǎn)化
隱式類型轉(zhuǎn)化主要原因是,表結(jié)構(gòu)中指定的數(shù)據(jù)類型與傳入的數(shù)據(jù)類型不同,導(dǎo)致索引無(wú)法使用。所以有兩種方案:
修改表結(jié)構(gòu),修改字段數(shù)據(jù)類型。
修改應(yīng)用,將應(yīng)用中傳入的字符類型改為與表結(jié)構(gòu)相同類型。
3. 為什么會(huì)選錯(cuò)索引3.1 優(yōu)化器選擇索引是優(yōu)化器的工作,其目的是找到一個(gè)更優(yōu)的執(zhí)行方案,用最小的代價(jià)去執(zhí)行語(yǔ)句。在數(shù)據(jù)庫(kù)中,掃描行數(shù)是影響執(zhí)行代價(jià)的因素之一。掃描的行數(shù)越少,意味著訪問(wèn)磁盤(pán)數(shù)據(jù)的次數(shù)越少,消耗的 CPU 資源越少。當(dāng)然,掃描行數(shù)并不是唯一的判斷標(biāo)準(zhǔn),優(yōu)化器還會(huì)結(jié)合是否使用臨時(shí)表、是否排序等因素進(jìn)行綜合判斷。
3.2 掃描行數(shù)
MySQL 在真正開(kāi)始執(zhí)行語(yǔ)句之前,并不能精確的知道滿足這個(gè)條件的記錄有多少條,只能通過(guò)索引的區(qū)分度來(lái)判斷。顯然,一個(gè)索引上不同的值越多,索引的區(qū)分度就越好,而一個(gè)索引上不同值的個(gè)數(shù)我們稱為“基數(shù)”,也就是說(shuō),這個(gè)基數(shù)越大,索引的區(qū)分度越好。# 通過(guò) show index 方法,查看索引的基數(shù)mysql> show index from t;++++++++++——+++-+| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |++++++++++——+++-+| t || PRIMARY || id| A|| NULL | NULL | | REE || || t || a|| a| A|| NULL | NULL | YES | REE || || t || b|| b| A|| NULL | NULL | YES | REE || |++++++++++——+++-+
MySQL 使用采樣統(tǒng)計(jì)方法來(lái)估算基數(shù):采樣統(tǒng)計(jì)的時(shí)候,InnoDB 默認(rèn)會(huì)選擇 N 個(gè)數(shù)據(jù)頁(yè),統(tǒng)計(jì)這些頁(yè)面上的不同值,得到一個(gè)平均值,然后乘以這個(gè)索引的頁(yè)面數(shù),就得到了這個(gè)索引的基數(shù)。而數(shù)據(jù)表是會(huì)持續(xù)更新的,索引統(tǒng)計(jì)信息也不會(huì)固定不變。所以,當(dāng)變更的數(shù)據(jù)行數(shù)超過(guò) 1/M 的時(shí)候,會(huì)自動(dòng)觸發(fā)重新做一次索引統(tǒng)計(jì)。
在 MySQL 中,有兩種存儲(chǔ)索引統(tǒng)計(jì)的方式,可以通過(guò)設(shè)置參數(shù) innodb_stats_persistent 的值來(lái)選擇:
on 表示統(tǒng)計(jì)信息會(huì)持久化存儲(chǔ)。默認(rèn) N = 20,M = 10。
off 表示統(tǒng)計(jì)信息只存儲(chǔ)在內(nèi)存中。默認(rèn) N = 8,M = 16。
由于是采樣統(tǒng)計(jì),所以不管 N 是 20 還是 8,這個(gè)基數(shù)都很容易不準(zhǔn)確。所以,冤有頭債有主,MySQL 選錯(cuò)索引,還得歸咎到?jīng)]能準(zhǔn)確地判斷出掃描行數(shù)。
可以用 yze table 來(lái)重新統(tǒng)計(jì)索引信息,進(jìn)行修正。
ANAZE TABLE tbl_name …
3.3 索引選擇異常和處理1. 采用 force index 強(qiáng)行選擇一個(gè)索引。2. 可以考慮修改語(yǔ)句,引導(dǎo) MySQL 使用我們期望的索引。3. 有些場(chǎng)景下,可以新建一個(gè)更合適的索引,來(lái)提供給優(yōu)化器做選擇,或刪掉誤用的索引。
如何正確合理的建立MYSQL數(shù)據(jù)庫(kù)索引
索引是快速搜索的關(guān)鍵。MySQL索引的建立對(duì)指笑于MySQL的高效運(yùn)行是很重要的。下面介紹幾種常見(jiàn)的MySQL索引類型。
在數(shù)據(jù)庫(kù)表中,對(duì)字段建立索引可以大大提高查詢速度。假如我們創(chuàng)建了一個(gè) mytable表:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL
); 我們隨機(jī)向里面插入了10000條記錄,其中有一條:5555, admin。
在查找username=”admin”的記錄 SELECT * FROM mytable WHERE
username=’admin’;時(shí),如果在username上已經(jīng)建立了索引,MySQL無(wú)須任何掃描,即準(zhǔn)確可找到該記錄。相反,MySQL會(huì)掃描所有記錄,即要查詢10000條記錄。
索引分單列索引和組合索引。單列索引,即一個(gè)索引只包含單個(gè)列,一個(gè)表可以有多個(gè)單列索引,但這不是組合索引。組合索引,即一個(gè)索包含多個(gè)列。
MySQL索引類型包括:
(1)普通索引
這是最基本的索引,它沒(méi)有任何限制。它有以下幾種創(chuàng)建方式:
◆創(chuàng)建索引
CREATE INDEX indexName ON mytable(username(length));
如果是CHAR,VARCHAR類型,length可以小于字段實(shí)際長(zhǎng)度;如果是BLOB和TEXT類型,必須指定 length,下同。
◆修改表結(jié)構(gòu)
ALTER mytable ADD INDEX ON (username(length))
◆創(chuàng)建表的時(shí)候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL,
INDEX (username(length)) ); 刪除索引的語(yǔ)法:
DROP INDEX ON mytable;
(2)唯一索引
它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種創(chuàng)建方式:
◆創(chuàng)建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length))
◆修改表結(jié)構(gòu)
ALTER mytable ADD UNIQUE ON (username(length))
◆創(chuàng)建表的時(shí)候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL,
UNIQUE (username(length)) );
(3)主鍵索引
它是一種特殊的唯一索引,不允許有空值。一般是在建表的時(shí)候同時(shí)創(chuàng)建主鍵則橡索引:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL,
PRIMARY KEY(ID) ); 當(dāng)然也可以用 ALTER 命令。記?。阂晃ǘ⒑瑐€(gè)表只能有一個(gè)主鍵。
(4)組合索引
為了形象地對(duì)比單列索引和組合索引,為表添加多個(gè)字段:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL,
city VARCHAR(50) NOT NULL, age INT NOT NULL );
為了進(jìn)一步榨取MySQL的效率,就要考慮建立組合索引。就是將 name, city, age建到一個(gè)索引里:
ALTER TABLE mytable ADD INDEX name_city_age (name(10),city,age);
建表時(shí),usernname長(zhǎng)度為 16,這里用
10。這是因?yàn)橐话闱闆r下名字的長(zhǎng)度不會(huì)超過(guò)10,這樣會(huì)加速索引查詢速度,還會(huì)減少索引文件的大小,提高INSERT的更新速度。
如果分別在
usernname,city,age上建立單列索引,讓該表有3個(gè)單列索引,查詢時(shí)和上述的組合索引效率也會(huì)大不一樣,遠(yuǎn)遠(yuǎn)低于我們的組合索引。雖然此時(shí)有了三個(gè)索引,但MySQL只能用到其中的那個(gè)它認(rèn)為似乎是最有效率的單列索引。
建立這樣的組合索引,其實(shí)是相當(dāng)于分別建立了下面三組組合索引:
usernname,city,age usernname,city usernname 為什么沒(méi)有
city,age這樣的組合索引呢?這是因?yàn)镸ySQL組合索引“最左前綴”的結(jié)果。簡(jiǎn)單的理解就是只從最左面的開(kāi)始組合。并不是只要包含這三列的查詢都會(huì)用到該組合索引,下面的幾個(gè)SQL就會(huì)用到這個(gè)組合索引:
SELECT * FROM mytable WHREE username=”admin” AND city=”鄭州” SELECT * FROM
mytable WHREE username=”admin” 而下面幾個(gè)則不會(huì)用到:
SELECT * FROM mytable WHREE age=20 AND city=”鄭州” SELECT * FROM mytable WHREE
city=”鄭州”
(5)建立索引的時(shí)機(jī)
到這里我們已經(jīng)學(xué)會(huì)了建立索引,那么我們需要在什么情況下建立索引呢?一般來(lái)說(shuō),在WHERE和JOIN中出現(xiàn)的列需要建立索引,但也不完全如此,因?yàn)镸ySQL只對(duì),>=,BETWEEN,IN,以及某些時(shí)候的LIKE才會(huì)使用索引。例如:
SELECT t.Name FROM mytable t LEFT JOIN mytable m ON t.Name=m.username
WHERE m.age=20 AND m.city=’鄭州’
此時(shí)就需要對(duì)city和age建立索引,由于mytable表的userame也出現(xiàn)在了JOIN子句中,也有對(duì)它建立索引的必要。
剛才提到只有某些時(shí)候的LIKE才需建立索引。因?yàn)樵谝酝ㄅ浞?和_開(kāi)頭作查詢時(shí),MySQL不會(huì)使用索引。例如下句會(huì)使用索引:
SELECT * FROM mytable WHERE username like’admin%’ 而下句就不會(huì)使用:
SELECT * FROM mytable WHEREt Name like’%admin’ 因此,在使用LIKE時(shí)應(yīng)注意以上的區(qū)別。
(6)索引的不足之處
上面都在說(shuō)使用索引的好處,但過(guò)多的使用索引將會(huì)造成濫用。因此索引也會(huì)有它的缺點(diǎn):
◆雖然索引大大提高了查詢速度,同時(shí)卻會(huì)降低更新表的速度,如對(duì)表進(jìn)行INSERT、UPDATE和DELETE。因?yàn)楦卤頃r(shí),MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件。
◆建立索引會(huì)占用磁盤(pán)空間的索引文件。一般情況這個(gè)問(wèn)題不太嚴(yán)重,但如果你在一個(gè)大表上創(chuàng)建了多種組合索引,索引文件的會(huì)膨脹很快。
索引只是提高效率的一個(gè)因素,如果你的MySQL有大數(shù)據(jù)量的表,就需要花時(shí)間研究建立更優(yōu)秀的索引,或優(yōu)化查詢語(yǔ)句。
(7)使用索引的注意事項(xiàng)
使用索引時(shí),有以下一些技巧和注意事項(xiàng):
◆索引不會(huì)包含有NULL值的列
只要列中包含有NULL值都將不會(huì)被包含在索引中,復(fù)合索引中只要有一列含有NULL值,那么這一列對(duì)于此復(fù)合索引就是無(wú)效的。所以我們?cè)跀?shù)據(jù)庫(kù)設(shè)計(jì)時(shí)不要讓字段的默認(rèn)值為NULL。
◆使用短索引
對(duì)串列進(jìn)行索引,如果可能應(yīng)該指定一個(gè)前綴長(zhǎng)度。例如,如果有一個(gè)CHAR(255)的列,如果在前10個(gè)或20個(gè)字符內(nèi),多數(shù)值是惟一的,那么就不要對(duì)整個(gè)列進(jìn)行索引。短索引不僅可以提高查詢速度而且可以節(jié)省磁盤(pán)空間和I/O操作。
◆索引列排序
MySQL查詢只使用一個(gè)索引,因此如果where子句中已經(jīng)使用了索引的話,那么order
by中的列是不會(huì)使用索引的。因此數(shù)據(jù)庫(kù)默認(rèn)排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個(gè)列的排序,如果需要更好給這些列創(chuàng)建復(fù)合索引。
◆like語(yǔ)句操作
一般情況下不鼓勵(lì)使用like操作,如果非使用不可,如何使用也是一個(gè)問(wèn)題。like “%aaa%” 不會(huì)使用索引而like
“aaa%”可以使用索引。
◆不要在列上進(jìn)行運(yùn)算
select * from users where YEAR(adddate)操作
以上,就對(duì)其中MySQL索引類型進(jìn)行了介紹。
MySQL索引類型包括:
(1)普通索引
這是最基本的索引,它沒(méi)有任何限制。它有以下幾種創(chuàng)建方式:
◆創(chuàng)建索引
CREATE INDEX indexName ON mytable(username(length)); 如果是CHAR,VARCHAR類型,length可以小于字段實(shí)際長(zhǎng)度;如果是BLOB和TEXT類型,必須指定 length,下同。
◆修改表結(jié)構(gòu)
ALTER mytable ADD INDEX ON (username(length))
◆創(chuàng)建表的時(shí)候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX (username(length)) ); 刪除索引的語(yǔ)法:
DROP INDEX ON mytable;
(2)唯一索引
與前面的普通索引類似空前察,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種創(chuàng)建方式:
◆創(chuàng)建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length))
◆修改表結(jié)構(gòu)
ALTER mytable ADD UNIQUE ON (username(length))
◆創(chuàng)建表的時(shí)候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE (username(length)) );
(3)主鍵索引
它是一種特殊的唯一索引,不允許有空值。一般是在建表的時(shí)候同時(shí)創(chuàng)建主鍵索斗茄引:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, PRIMARY KEY(ID) ); 當(dāng)然也可以用 ALTER 命令。記?。阂粋€(gè)表只能有一個(gè)主鍵。
(4)組合索引
為了形象地對(duì)比單列索引和組合索引,為表添加悔物多個(gè)字段:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, city VARCHAR(50) NOT NULL, age INT NOT NULL ); 為了進(jìn)一步榨取MySQL的效率,就要考慮建立組合索引。就是將 name, city, age建到一個(gè)索引里:
ALTER TABLE mytable ADD INDEX name_city_age (name(10),city,age); 建表時(shí),usernname長(zhǎng)度為 16,這里用 10。這是因?yàn)橐话闱闆r下名字的長(zhǎng)度不會(huì)超過(guò)10,這樣會(huì)加速索引查詢速度,還會(huì)減少索引文件的大小,提高INSERT的更新速度。
如果分別在 usernname,city,age上建立單列索引,讓該表有3個(gè)單列索引,查詢時(shí)和上述的組合索引效率也會(huì)大不一樣,遠(yuǎn)遠(yuǎn)低于我們的組合索引。雖然此時(shí)有了三個(gè)索引,但MySQL只能用到其中的那個(gè)它認(rèn)為似乎是最有效率的單列索引。
建立這樣的組合索引,其實(shí)是相當(dāng)于分別建立了下面三組組合索引:
usernname,city,age usernname,city usernname 為什么沒(méi)有 city,age這樣的組合索引呢?這是因?yàn)镸ySQL組合索引“最左前綴”的結(jié)果。簡(jiǎn)單的理解就是只從最左面的開(kāi)始組合。并不是只要包含這三列的查詢都會(huì)用到該組合索引,下面的幾個(gè)SQL就會(huì)用到這個(gè)組合索引:
SELECT * FROM mytable WHREE username=”admin” AND city=”鄭州” SELECT * FROM mytable WHREE username=”admin” 而下面幾個(gè)則不會(huì)用到:
SELECT * FROM mytable WHREE age=20 AND city=”鄭州” SELECT * FROM mytable WHREE city=”鄭州”
(5)建立索引的時(shí)機(jī)
一般來(lái)說(shuō),在WHERE和JOIN中出現(xiàn)的列需要建立索引,但也不完全如此,因?yàn)镸ySQL只對(duì),>=,BETWEEN,IN,以及某些時(shí)候的LIKE才會(huì)使用索引。例如:
SELECT t.Name FROM mytable t LEFT JOIN mytable m ON t.Name=m.username WHERE m.age=20 AND m.city=’鄭州’ 此時(shí)就需要對(duì)city和age建立索引,由于mytable表的userame也出現(xiàn)在了JOIN子句中,也有對(duì)它建立索引的必要。
剛才提到只有某些時(shí)候的LIKE才需建立索引。因?yàn)樵谝酝ㄅ浞?和_開(kāi)頭作查詢時(shí),MySQL不會(huì)使用索引。例如下句會(huì)使用索引:
SELECT * FROM mytable WHERE username like’admin%’ 而下句就不會(huì)使用:
SELECT * FROM mytable WHEREt Name like’%admin’ 因此,在使用LIKE時(shí)應(yīng)注意以上的區(qū)別。
(6)索引的不足之處
上面都在說(shuō)使用索引的好處,但過(guò)多的使用索引將會(huì)造成濫用。因此索引也會(huì)有它的缺點(diǎn):
◆雖然索引大大提高了查詢速度,同時(shí)卻會(huì)降低更新表的速度,如對(duì)表進(jìn)行INSERT、UPDATE和DELETE。因?yàn)楦卤頃r(shí),MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件。
◆建立索引會(huì)占用磁盤(pán)空間的索引文件。一般情況這個(gè)問(wèn)題不太嚴(yán)重,但如果你在一個(gè)大表上創(chuàng)建了多種組合索引,索引文件的會(huì)膨脹很快。
索引只是提高效率的一個(gè)因素,如果你的MySQL有大數(shù)據(jù)量的表,就需要花時(shí)間研究建立更優(yōu)秀的索引,或優(yōu)化查詢語(yǔ)句。
(7)使用索引的注意事項(xiàng)
使用索引時(shí),有以下一些技巧和注意事項(xiàng):
◆索引不會(huì)包含有NULL值的列
只要列中包含有NULL值都將不會(huì)被包含在索引中,復(fù)合索引中只要有一列含有NULL值,那么這一列對(duì)于此復(fù)合索引就是無(wú)效的。所以我們?cè)跀?shù)據(jù)庫(kù)設(shè)計(jì)時(shí)不要讓字段的默認(rèn)值為NULL。
◆使用短索引
對(duì)串列進(jìn)行索引,如果可能應(yīng)該指定一個(gè)前綴長(zhǎng)度。例如,如果有一個(gè)CHAR(255)的列,如果在前10個(gè)或20個(gè)字符內(nèi),多數(shù)值是惟一的,那么就不要對(duì)整個(gè)列進(jìn)行索引。短索引不僅可以提高查詢速度而且可以節(jié)省磁盤(pán)空間和I/O操作。
◆索引列排序
MySQL查詢只使用一個(gè)索引,因此如果where子句中已經(jīng)使用了索引的話,那么order by中的列是不會(huì)使用索引的。因此數(shù)據(jù)庫(kù)默認(rèn)排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個(gè)列的排序,如果需要更好給這些列創(chuàng)建復(fù)合索引。
◆like語(yǔ)句操作
一般情況下不鼓勵(lì)使用like操作,如果非使用不可,如何使用也是一個(gè)問(wèn)題。like “%aaa%” 不會(huì)使用索引而like “aaa%”可以使用索引。
◆不要在列上進(jìn)行運(yùn)算
select * from users where YEAR(adddate)操作
MySQL 數(shù)據(jù)庫(kù)索引是可以提高數(shù)據(jù)庫(kù)查詢速度的重要因素之一,下面分享幾個(gè)正確合理的建立 MYSQL 數(shù)據(jù)庫(kù)索引的方法:1. 找到仿碧常用的查詢語(yǔ)句可以通過(guò)慢查詢?nèi)罩镜确绞秸页鲎畛S玫牟樵冋Z(yǔ)句,然后對(duì)這些查詢語(yǔ)句的字段建立索引。這樣可以極大地加快這些經(jīng)常使用的查詢語(yǔ)句的速度。2. 考慮選擇性索引的選擇性是指索引字段的唯一性和重復(fù)性,選擇性越高,租寬查詢效率越高。例如, Boolean 類型字段的選擇性非常低,只有兩個(gè)值,可能會(huì)降低索引效率。3. 對(duì)頻繁修改的字段慎重建立索引頻繁修改的字段如日期或訂單狀態(tài)等,會(huì)導(dǎo)致索引頻繁變動(dòng),這會(huì)影響性能。建議對(duì)頻繁修改的字段慎重建立索引。4. 聯(lián)合索引適當(dāng)使用聯(lián)合索引可提高查詢效率,因?yàn)槎嗔新?lián)合索引可以讓 WHERE 子句篩選數(shù)據(jù)更準(zhǔn)確。5. 考慮多表關(guān)聯(lián)當(dāng)多個(gè)表關(guān)聯(lián)查詢時(shí),可以使用外鍵約束來(lái)建立索引,以確保在關(guān)聯(lián)查備型舉詢時(shí)能夠快速獲取相關(guān)數(shù)據(jù)。6. 定期維護(hù)索引建立索引后也要對(duì)索引進(jìn)行維護(hù),例如定期使用 ANAZE TABLES 命令進(jìn)行優(yōu)化和修復(fù)。
MySQL索引類型包括:
(1)普通索引
這是最基本的索引,它沒(méi)有任何限制。它有以下幾種創(chuàng)建方式:
◆創(chuàng)建索引
CREATE INDEX indexName ON mytable(username(length)); 如果是CHAR,VARCHAR類型,length可以小于字段實(shí)際長(zhǎng)度;如果是BLOB和TEXT類型,必須指定 length,下同。
◆修改表結(jié)構(gòu)
ALTER mytable ADD INDEX ON (username(length))
◆創(chuàng)建表的時(shí)候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX (username(length)) ); 刪除索引的語(yǔ)法:
DROP INDEX ON mytable;
(2)唯一索引
與前面的普通索引類似空前察,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種創(chuàng)建方式:
◆創(chuàng)建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length))
◆修改表結(jié)構(gòu)
ALTER mytable ADD UNIQUE ON (username(length))
◆創(chuàng)建表的時(shí)候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE (username(length)) );
(3)主鍵索引
它是一種特殊的唯一索引,不允許有空值。一般是在建表的時(shí)候同時(shí)創(chuàng)建主鍵索斗茄引:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, PRIMARY KEY(ID) ); 當(dāng)然也可以用 ALTER 命令。記住:一個(gè)表只能有一個(gè)主鍵。
(4)組合索引
為了形象地對(duì)比單列索引和組合索引,為表添加悔物多個(gè)字段:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, city VARCHAR(50) NOT NULL, age INT NOT NULL ); 為了進(jìn)一步榨取MySQL的效率,就要考慮建立組合索引。就是將 name, city, age建到一個(gè)索引里:
ALTER TABLE mytable ADD INDEX name_city_age (name(10),city,age); 建表時(shí),usernname長(zhǎng)度為 16,這里用 10。這是因?yàn)橐话闱闆r下名字的長(zhǎng)度不會(huì)超過(guò)10,這樣會(huì)加速索引查詢速度,還會(huì)減少索引文件的大小,提高INSERT的更新速度。
如果分別在 usernname,city,age上建立單列索引,讓該表有3個(gè)單列索引,查詢時(shí)和上述的組合索引效率也會(huì)大不一樣,遠(yuǎn)遠(yuǎn)低于我們的組合索引。雖然此時(shí)有了三個(gè)索引,但MySQL只能用到其中的那個(gè)它認(rèn)為似乎是最有效率的單列索引。
建立這樣的組合索引,其實(shí)是相當(dāng)于分別建立了下面三組組合索引:
usernname,city,age usernname,city usernname 為什么沒(méi)有 city,age這樣的組合索引呢?這是因?yàn)镸ySQL組合索引“最左前綴”的結(jié)果。簡(jiǎn)單的理解就是只從最左面的開(kāi)始組合。并不是只要包含這三列的查詢都會(huì)用到該組合索引,下面的幾個(gè)SQL就會(huì)用到這個(gè)組合索引:
SELECT * FROM mytable WHREE username=”admin” AND city=”鄭州” SELECT * FROM mytable WHREE username=”admin” 而下面幾個(gè)則不會(huì)用到:
SELECT * FROM mytable WHREE age=20 AND city=”鄭州” SELECT * FROM mytable WHREE city=”鄭州”
(5)建立索引的時(shí)機(jī)
一般來(lái)說(shuō),在WHERE和JOIN中出現(xiàn)的列需要建立索引,但也不完全如此,因?yàn)镸ySQL只對(duì),>=,BETWEEN,IN,以及某些時(shí)候的LIKE才會(huì)使用索引。例如:
SELECT t.Name FROM mytable t LEFT JOIN mytable m ON t.Name=m.username WHERE m.age=20 AND m.city=’鄭州’ 此時(shí)就需要對(duì)city和age建立索引,由于mytable表的userame也出現(xiàn)在了JOIN子句中,也有對(duì)它建立索引的必要。
剛才提到只有某些時(shí)候的LIKE才需建立索引。因?yàn)樵谝酝ㄅ浞?和_開(kāi)頭作查詢時(shí),MySQL不會(huì)使用索引。例如下句會(huì)使用索引:
SELECT * FROM mytable WHERE username like’admin%’ 而下句就不會(huì)使用:
SELECT * FROM mytable WHEREt Name like’%admin’ 因此,在使用LIKE時(shí)應(yīng)注意以上的區(qū)別。
(6)索引的不足之處
上面都在說(shuō)使用索引的好處,但過(guò)多的使用索引將會(huì)造成濫用。因此索引也會(huì)有它的缺點(diǎn):
◆雖然索引大大提高了查詢速度,同時(shí)卻會(huì)降低更新表的速度,如對(duì)表進(jìn)行INSERT、UPDATE和DELETE。因?yàn)楦卤頃r(shí),MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件。
◆建立索引會(huì)占用磁盤(pán)空間的索引文件。一般情況這個(gè)問(wèn)題不太嚴(yán)重,但如果你在一個(gè)大表上創(chuàng)建了多種組合索引,索引文件的會(huì)膨脹很快。
索引只是提高效率的一個(gè)因素,如果你的MySQL有大數(shù)據(jù)量的表,就需要花時(shí)間研究建立更優(yōu)秀的索引,或優(yōu)化查詢語(yǔ)句。
(7)使用索引的注意事項(xiàng)
使用索引時(shí),有以下一些技巧和注意事項(xiàng):
◆索引不會(huì)包含有NULL值的列
只要列中包含有NULL值都將不會(huì)被包含在索引中,復(fù)合索引中只要有一列含有NULL值,那么這一列對(duì)于此復(fù)合索引就是無(wú)效的。所以我們?cè)跀?shù)據(jù)庫(kù)設(shè)計(jì)時(shí)不要讓字段的默認(rèn)值為NULL。
◆使用短索引
對(duì)串列進(jìn)行索引,如果可能應(yīng)該指定一個(gè)前綴長(zhǎng)度。例如,如果有一個(gè)CHAR(255)的列,如果在前10個(gè)或20個(gè)字符內(nèi),多數(shù)值是惟一的,那么就不要對(duì)整個(gè)列進(jìn)行索引。短索引不僅可以提高查詢速度而且可以節(jié)省磁盤(pán)空間和I/O操作。
◆索引列排序
MySQL查詢只使用一個(gè)索引,因此如果where子句中已經(jīng)使用了索引的話,那么order by中的列是不會(huì)使用索引的。因此數(shù)據(jù)庫(kù)默認(rèn)排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個(gè)列的排序,如果需要更好給這些列創(chuàng)建復(fù)合索引。
◆like語(yǔ)句操作
一般情況下不鼓勵(lì)使用like操作,如果非使用不可,如何使用也是一個(gè)問(wèn)題。like “%aaa%” 不會(huì)使用索引而like “aaa%”可以使用索引。
◆不要在列上進(jìn)行運(yùn)算
數(shù)據(jù)庫(kù)中如何創(chuàng)建一個(gè)復(fù)合索引的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于數(shù)據(jù)庫(kù)中如何創(chuàng)建一個(gè)復(fù)合索引,如何在數(shù)據(jù)庫(kù)中創(chuàng)建復(fù)合索引,如何正確合理的建立MYSQL數(shù)據(jù)庫(kù)索引的信息別忘了在本站進(jìn)行查找喔。
成都創(chuàng)新互聯(lián)科技有限公司,是一家專注于互聯(lián)網(wǎng)、IDC服務(wù)、應(yīng)用軟件開(kāi)發(fā)、網(wǎng)站建設(shè)推廣的公司,為客戶提供互聯(lián)網(wǎng)基礎(chǔ)服務(wù)!
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡(jiǎn)單好用,價(jià)格厚道的香港/美國(guó)云服務(wù)器和獨(dú)立服務(wù)器。創(chuàng)新互聯(lián)——四川成都IDC機(jī)房服務(wù)器托管/機(jī)柜租用。為您精選優(yōu)質(zhì)idc數(shù)據(jù)中心機(jī)房租用、服務(wù)器托管、機(jī)柜租賃、大帶寬租用,高電服務(wù)器托管,算力服務(wù)器租用,可選線路電信、移動(dòng)、聯(lián)通機(jī)房等。
分享文章:如何在數(shù)據(jù)庫(kù)中創(chuàng)建復(fù)合索引(數(shù)據(jù)庫(kù)中如何創(chuàng)建一個(gè)復(fù)合索引)
網(wǎng)頁(yè)路徑:http://m.fisionsoft.com.cn/article/cohdcie.html


咨詢
建站咨詢
