數(shù)據(jù)庫索引的使用方法_第1頁
數(shù)據(jù)庫索引的使用方法_第2頁
數(shù)據(jù)庫索引的使用方法_第3頁
數(shù)據(jù)庫索引的使用方法_第4頁
數(shù)據(jù)庫索引的使用方法_第5頁
已閱讀5頁,還剩1頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1/1數(shù)據(jù)庫索引的使用方法數(shù)據(jù)庫索引的使用方法

走向精通MySQL的道路非常的艱難,還好各種關(guān)系型數(shù)據(jù)庫大同小異,足夠讓我從增刪改查上升到高性能數(shù)據(jù)庫的架構(gòu)和調(diào)優(yōu)。這期間的各種概念就不絮叨了,我也很難表述的很清楚,昨天寫了個小腳本往我本機MySQL數(shù)據(jù)庫的某張表里面注入了200萬條數(shù)據(jù)(Windows7旗艦版/1.66GHz/2G內(nèi)存/MySQL5.1.50),數(shù)據(jù)表的結(jié)構(gòu)如下圖所示,屬于一個比較基本的定長表,考慮到我可憐的本本的承受能力,id使用從1開始的自增,title字段為隨機20個標題中的一個,content都是相同的內(nèi)容,time使用時間戳而非datetime類型,即10位整型數(shù)據(jù)。

就是這么一個結(jié)構(gòu)極其簡單的表,200萬數(shù)量級的復(fù)雜查詢將會變的非常緩慢,比如執(zhí)行下面的SQL語句。

SELECTa.id,FROM_UNIXTIME(a.time)

FROMarticleASa

WHEREa.title=‘PHP筆試題和答案——基礎(chǔ)語言方面’

查詢時間基本上需要50-100秒,這個是非??植赖?,如果加上聯(lián)合查詢和其他一些約束條件,數(shù)據(jù)庫會瘋狂的消耗內(nèi)存。

如果這時候數(shù)據(jù)庫里面針對title字段建立了索引,查詢效率將會大幅度提升,如下圖所示??梢妼τ诖笮蛿?shù)據(jù)庫,建立索引是非常非常重要的一個優(yōu)化手段(當然還會有很多其他優(yōu)化這樣的數(shù)據(jù)庫的方法,但是本文主題所限,暫不討論。),廢話了這么多,以下開始總結(jié)MySQL中索引的使用方法和性能優(yōu)化以及一些注意事項。

索引的概念

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

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

索引的類型

1.普通索引

這是最基本的索引,它沒有任何限制,比如上文中為title字段創(chuàng)建的索引就是一個普通索引。

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

CREATEINDEXindexNameONtable(column(length))

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

ALTERtableADDINDEXindexNameON(column(length))

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

CREATETABLE`table`(

`id`int(11)NOTNULLAUTO_INCREMENT,

`title`255)CHARACTERSETutf8COLLATEutf8_general_ciNOTNULL,

`content`textCHARACTERSETutf8COLLATEutf8_general_ciNULL,

`time`int(10)NULLDEFAULTNULL,

PRIMARYKEY(`id`),

INDEXindexName(title(length))

)

–刪除索引

DROPINDEXindexNameONtable

2.唯一索引

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

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

CREATEUNIQUEINDEXindexNameONtable(column(length))

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

ALTERtableADDUNIQUEindexNameON(column(length))

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

CREATETABLE`table`(

`id`int(11)NOTNULLAUTO_INCREMENT,

`title`255)CHARACTERSETutf8COLLATEutf8_general_ciNOTNULL,

`content`textCHARACTERSETutf8COLLATEutf8_general_ciNULL,

`time`int(10)NULLDEFAULTNULL,

PRIMARYKEY(`id`),

UNIQUEindexName(title(length))

);

3.全文索引(FULLTEXT)

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

–創(chuàng)建表的適合添加全文索引

CREATETABLE`table`(

`id`int(11)NOTNULLAUTO_INCREMENT,

`title`255)CHARACTERSETutf8COLLATEutf8_general_ciNOTNULL,

`content`textCHARACTERSETutf8COLLATEutf8_general_ciNULL,

`time`int(10)NULLDEFAULTNULL,

PRIMARYKEY(`id`),

FULLTEXT(content)

);

–修改表結(jié)構(gòu)添加全文索引

ALTERTABLEarticleADDFULLTEXTindex_content(content)

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

CREATEFULLTEXTINDEXindex_contentONarticle(content)

4.單列索引、多列索引

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

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

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

–title,time

–title

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

–使用到上面的索引

SELECT*FROMarticleWHREEtitle=“PHP程序員”ANDtime=1234567890

SELECT*FROMarticleWHREEutitle=“PHP程序員”

–不使用上面的索引

SELECT*FROMarticleWHREEtime=1234567890

MySQL索引的優(yōu)化

上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件。建立索引會占用磁盤空間的索引文件。一般情況這個問題不太嚴重,但如果你在一個大表上創(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ù)一項。比如您的某個表有一個時間列,恰好您把聚合索引建立在了該列,這時您查詢2023年1月1日至2023年10月1日之間的全部數(shù)據(jù)時,這個速度就將是很快的,因為您的這本字典正文是按日期進行排序的,聚類索引只需要找到要檢索的所有數(shù)據(jù)中的開頭和結(jié)尾數(shù)據(jù)即可;而不像非聚集索引,必須先查到目錄中查到每一項數(shù)據(jù)對應(yīng)的頁碼,然后再根據(jù)頁碼查到具體內(nèi)容。其實這個具體用法我還不是很理解,只能等待后期的項目開發(fā)中慢慢學(xué)學(xué)了。

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

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

3.使用短索引

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

4.索引列排序

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

5.like語句操作

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

6.不要在列上進行運算

例如:select*fromuserswhereYEAR(adddate)2023,將在每個行上進行運算,這將導(dǎo)致索引失效而進行全表掃描,因此我們可以改成:select*fromuserswhereadddate’2023-01-01′。關(guān)于這一點可以

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論