佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > 詳解mysql索引總結(jié)----mysql索引類型以及創(chuàng)建

詳解mysql索引總結(jié)----mysql索引類型以及創(chuàng)建

熱門標(biāo)簽:網(wǎng)站排名優(yōu)化 鐵路電話系統(tǒng) 百度競價排名 服務(wù)外包 Linux服務(wù)器 AI電銷 呼叫中心市場需求 地方門戶網(wǎng)站

關(guān)于MySQL索引的好處,如果正確合理設(shè)計并且使用索引的MySQL是一輛蘭博基尼的話,那么沒有設(shè)計和使用索引的MySQL就是一個人力三輪車。對于沒有索引的表,單表查詢可能幾十萬數(shù)據(jù)就是瓶頸,而通常大型網(wǎng)站單日就可能會產(chǎn)生幾十萬甚至幾百萬的數(shù)據(jù),沒有索引查詢會變的非常緩慢。還是以WordPress來說,其多個數(shù)據(jù)表都會對經(jīng)常被查詢的字段添加索引,比如wp_comments表中針對5個字段設(shè)計了BTREE索引。

 一個簡單的對比測試

以我去年測試的數(shù)據(jù)作為一個簡單示例,20多條數(shù)據(jù)源隨機生成200萬條數(shù)據(jù),平均每條數(shù)據(jù)源都重復(fù)大概10萬次,表結(jié)構(gòu)比較簡單,僅包含一個自增ID,一個char類型,一個text類型和一個int類型,單表2G大小,使用MyIASM引擎。開始測試未添加任何索引。

執(zhí)行下面的SQL語句:

mysql> SELECT id,FROM_UNIXTIME(time) FROM article WHERE a.title='測試標(biāo)題' 

查詢需要的時間非??植赖模绻由下?lián)合查詢和其他一些約束條件,數(shù)據(jù)庫會瘋狂的消耗內(nèi)存,并且會影響前端程序的執(zhí)行。這時給title字段添加一個BTREE索引:

mysql> ALTER TABLE article ADD INDEX index_article_title ON title(200); 

再次執(zhí)行上述查詢語句,其對比非常明顯:

MySQL索引的概念

索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個組成部分),它們包含著對數(shù)據(jù)表里所有記錄的引用指針。更通俗的說,數(shù)據(jù)庫索引好比是一本書前面的目錄,能加快數(shù)據(jù)庫的查詢速度。上述SQL語句,在沒有索引的情況下,數(shù)據(jù)庫會遍歷全部200條數(shù)據(jù)后選擇符合條件的;而有了相應(yīng)的索引之后,數(shù)據(jù)庫會直接在索引中查找符合條件的選項。如果我們把SQL語句換成“SELECT * FROM article WHERE id=2000000”,那么你是希望數(shù)據(jù)庫按照順序讀取完200萬行數(shù)據(jù)以后給你結(jié)果還是直接在索引中定位呢?上面的兩個圖片鮮明的用時對比已經(jīng)給出了答案(注:一般數(shù)據(jù)庫默認(rèn)都會為主鍵生成索引)。

索引分為聚簇索引和非聚簇索引兩種,聚簇索引是按照數(shù)據(jù)存放的物理位置為順序的,而非聚簇索引就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對于單行的檢索很快。

 MySQL索引的類型

1. 普通索引

這是最基本的索引,它沒有任何限制,比如上文中為title字段創(chuàng)建的索引就是一個普通索引,MyIASM中默認(rèn)的BTREE類型的索引,也是我們大多數(shù)情況下用到的索引。

 –直接創(chuàng)建索引 

CREATE INDEX index_name ON table(column(length)) 

–修改表結(jié)構(gòu)的方式添加索引 

ALTER TABLE table_name ADD INDEX index_name ON (column(length)) 

–創(chuàng)建表的時候同時創(chuàng)建索引 

CREATE TABLE `table` ( 


 `id` int(11) NOT NULL AUTO_INCREMENT , 


 `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , 


 `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL , 


 `time` int(10) NULL DEFAULT NULL , 


 PRIMARY KEY (`id`), 


 INDEX index_name (title(length)) 


 ) 

–刪除索引 

DROP INDEX index_name ON table 

2. 唯一索引

與普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值(注意和主鍵不同)。如果是組合索引,則列值的組合必須唯一,創(chuàng)建方法和普通索引類似。

–創(chuàng)建唯一索引 


 CREATE UNIQUE INDEX indexName ON table(column(length)) 


 –修改表結(jié)構(gòu) 


 ALTER TABLE table_name ADD UNIQUE indexName ON (column(length)) 


 –創(chuàng)建表的時候直接指定 


 CREATE TABLE `table` ( 


 `id` int(11) NOT NULL AUTO_INCREMENT , 


 `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , 


 `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL , 


 `time` int(10) NULL DEFAULT NULL , 


 PRIMARY KEY (`id`), 


 UNIQUE indexName (title(length)) 


 ); 

3. 全文索引(FULLTEXT)

MySQL從3.23.23版開始支持全文索引和全文檢索,F(xiàn)ULLTEXT索引僅可用于 MyISAM 表;他們可以從CHAR、VARCHAR或TEXT列中作為CREATE TABLE語句的一部分被創(chuàng)建,或是隨后使用ALTER TABLE 或CREATE INDEX被添加。////對于較大的數(shù)據(jù)集,將你的資料輸入一個沒有FULLTEXT索引的表中,然后創(chuàng)建索引,其速度比把資料輸入現(xiàn)有FULLTEXT索引的速度更為快。不過切記對于大容量的數(shù)據(jù)表,生成全文索引是一個非常消耗時間非常消耗硬盤空間的做法。

 –創(chuàng)建表的適合添加全文索引 
CREATE TABLE `table` ( 
`id` int(11) NOT NULL AUTO_INCREMENT , 
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , 
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL , 
`time` int(10) NULL DEFAULT NULL , 
PRIMARY KEY (`id`), 
FULLTEXT (content) 
 ); 
 –修改表結(jié)構(gòu)添加全文索引 
ALTER TABLE article ADD FULLTEXT index_content(content) 
–直接創(chuàng)建索引 
CREATE FULLTEXT INDEX index_content ON article(content) 

4. 單列索引、多列索引

多個單列索引與單個多列索引的查詢效果不同,因為執(zhí)行查詢時,MySQL只能使用一個索引,會從多個索引中選擇一個限制最為嚴(yán)格的索引。

5. 組合索引(最左前綴)

平時用的SQL查詢語句一般都有比較多的限制條件,所以為了進(jìn)一步榨取MySQL的效率,就要考慮建立組合索引。例如上表中針對title和time建立一個組合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。建立這樣的組合索引,其實是相當(dāng)于分別建立了下面兩組組合索引:

–title,time

–title

為什么沒有time這樣的組合索引呢?這是因為MySQL組合索引“最左前綴”的結(jié)果。簡單的理解就是只從最左面的開始組合。并不是只要包含這兩列的查詢都會用到該組合索引,如下面的幾個SQL所示:

 –使用到上面的索引 
SELECT * FROM article WHREE title='測試' AND time=1234567890; 
SELECT * FROM article WHREE utitle='測試';

–不使用上面的索引 
SELECT * FROM article WHREE time=1234567890;

 MySQL索引的優(yōu)化

上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進(jìn)行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件。建立索引會占用磁盤空間的索引文件。一般情況這個問題不太嚴(yán)重,但如果你在一個大表上創(chuàng)建了多種組合索引,索引文件的會膨脹很快。索引只是提高效率的一個因素,如果你的MySQL有大數(shù)據(jù)量的表,就需要花時間研究建立最優(yōu)秀的索引,或優(yōu)化查詢語句。下面是一些總結(jié)以及收藏的MySQL索引的注意事項和優(yōu)化方法。

1. 何時使用聚集索引或非聚集索引?

動作描述 使用聚集索引 使用非聚集索引
列經(jīng)常被分組排序 使用 使用
返回某范圍內(nèi)的數(shù)據(jù) 使用 不使用
一個或極少不同值 不使用 不使用
小數(shù)目的不同值 使用 不使用
大數(shù)目的不同值 不使用 使用
頻繁更新的列 不使用 使用
外鍵列 使用 使用
主鍵列 使用 使用
頻繁修改索引列 不使用 使用

事實上,我們可以通過前面聚集索引和非聚集索引的定義的例子來理解上表。如:返回某范圍內(nèi)的數(shù)據(jù)一項。比如您的某個表有一個時間列,恰好您把聚合索引建立在了該列,這時您查詢2004年1月1日至2004年10月1日之間的全部數(shù)據(jù)時,這個速度就將是很快的,因為您的這本字典正文是按日期進(jìn)行排序的,聚類索引只需要找到要檢索的所有數(shù)據(jù)中的開頭和結(jié)尾數(shù)據(jù)即可;而不像非聚集索引,必須先查到目錄中查到每一項數(shù)據(jù)對應(yīng)的頁碼,然后再根據(jù)頁碼查到具體內(nèi)容。其實這個具體用法我還不是很理解,只能等待后期的項目開發(fā)中慢慢學(xué)學(xué)了。

2. 索引不會包含有NULL值的列

只要列中包含有NULL值都將不會被包含在索引中,復(fù)合索引中只要有一列含有NULL值,那么這一列對于此復(fù)合索引就是無效的。所以我們在數(shù)據(jù)庫設(shè)計時不要讓字段的默認(rèn)值為NULL。

3. 使用短索引

對串列進(jìn)行索引,如果可能應(yīng)該指定一個前綴長度。例如,如果有一個CHAR(255)的列,如果在前10個或20個字符內(nèi),多數(shù)值是惟一的,那么就不要對整個列進(jìn)行索引。短索引不僅可以提高查詢速度而且可以節(jié)省磁盤空間和I/O操作。

4. 索引列排序

MySQL查詢只使用一個索引,因此如果where子句中已經(jīng)使用了索引的話,那么order by中的列是不會使用索引的。因此數(shù)據(jù)庫默認(rèn)排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個列的排序,如果需要最好給這些列創(chuàng)建復(fù)合索引。

5. like語句操作

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

6. 不要在列上進(jìn)行運算

例如:select * from users where YEAR(adddate)2007,將在每個行上進(jìn)行運算,這將導(dǎo)致索引失效而進(jìn)行全表掃描,因此我們可以改成:select * from users where adddate'2007-01-01′。關(guān)于這一點可以圍觀:一個單引號引發(fā)的MYSQL性能損失。

最后總結(jié)一下,MySQL只對一下操作符才使用索引:,=,=,>,>=,between,in,以及某些時候的like(不以通配符%或_開頭的情形)。而理論上每張表里面最多可創(chuàng)建16個索引,不過除非是數(shù)據(jù)量真的很多,否則過多的使用索引也不是那么好玩的,比如我剛才針對text類型的字段創(chuàng)建索引的時候,系統(tǒng)差點就卡死了。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • MySQL 索引的優(yōu)缺點以及創(chuàng)建索引的準(zhǔn)則
  • MySQL字符串索引更合理的創(chuàng)建規(guī)則討論
  • MySQL使用命令創(chuàng)建、刪除、查詢索引的介紹
  • 怎樣正確創(chuàng)建MySQL索引的方法詳解
  • 圖文詳解MySQL中兩表關(guān)聯(lián)的連接表如何創(chuàng)建索引
  • MySQL創(chuàng)建全文索引分享
  • MySQL查看、創(chuàng)建和刪除索引的方法
  • mysql 添加索引 mysql 如何創(chuàng)建索引
  • MySQL創(chuàng)建索引需要了解的

標(biāo)簽:仙桃 黃山 蘭州 銅川 湘潭 衡水 崇左 湖南

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解mysql索引總結(jié)----mysql索引類型以及創(chuàng)建》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    南开区| 布尔津县| 石台县| 涪陵区| 会泽县| 昌平区| 波密县| 田林县| 常山县| 资源县| 科尔| 通许县| 环江| 寿宁县| 临夏市| 滨海县| 黄陵县| 延寿县| 尉氏县| 桂东县| 桂平市| 黎城县| 沁源县| 深水埗区| 湖州市| 临朐县| 茶陵县| 太湖县| 临江市| 论坛| 木里| 平罗县| 伊宁市| 出国| 卢湾区| 东台市| 都安| 高邮市| 樟树市| 桐梓县| 台湾省|