走向精通MySQL的道路非常的艱難,還好各種關(guān)系型數(shù)據(jù)庫大同小異,足夠讓我從增刪改查上升到高性能數(shù)據(jù)庫的架構(gòu)和調(diào)優(yōu)。這期間的各種概念就不絮叨了,我也很難表述的很清楚,昨天寫了個(gè)小腳本往我本機(jī)MySQL數(shù)據(jù)庫的某張表里面注入了200萬條數(shù)據(jù)(Windows7旗艦
走向精通MySQL的道路非常的艱難,還好各種關(guān)系型數(shù)據(jù)庫大同小異,足夠讓我從增刪改查上升到高性能數(shù)據(jù)庫的架構(gòu)和調(diào)優(yōu)。這期間的各種概念就不絮叨了,我也很難表述的很清楚,昨天寫了個(gè)小腳本往我本機(jī)MySQL數(shù)據(jù)庫的某張表里面注入了200萬條數(shù)據(jù)(Windows7旗艦版/1.66GHz/2G內(nèi)存/MySQL5.1.50),數(shù)據(jù)表的結(jié)構(gòu)如下圖所示,屬于一個(gè)比較基本的定長表,考慮到我可憐的本本的承受能力,id使用從1開始的自增,title字段為隨機(jī)20個(gè)標(biāo)題中的一個(gè),content都是相同的內(nèi)容,time使用時(shí)間戳而非datetime類型,即10位整型數(shù)據(jù)。
就是這么一個(gè)結(jié)構(gòu)極其簡單的表,200萬數(shù)量級的復(fù)雜查詢將會(huì)變的非常緩慢,比如執(zhí)行下面的SQL語句。
SELECT a.id,FROM_UNIXTIME(a.time)
FROM article AS a
WHERE a.title=‘PHP筆試題和答案——基礎(chǔ)語言方面’
查詢時(shí)間基本上需要50-100秒,這個(gè)是非??植赖模绻由下?lián)合查詢和其他一些約束條件,數(shù)據(jù)庫會(huì)瘋狂的消耗內(nèi)存。
如果這時(shí)候數(shù)據(jù)庫里面針對title字段建立了索引,查詢效率將會(huì)大幅度提升,如下圖所示??梢妼τ诖笮蛿?shù)據(jù)庫,建立索引是非常非常重要的一個(gè)優(yōu)化手段(當(dāng)然還會(huì)有很多其他優(yōu)化這樣的數(shù)據(jù)庫的方法,但是本文主題所限,暫不討論。),廢話了這么多,以下開始總結(jié)MySQL中索引的使用方法和性能優(yōu)化以及一些注意事項(xiàng)。
索引的概念
索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分),它們包含著對數(shù)據(jù)表里所有記錄的引用指針。更通俗的說,數(shù)據(jù)庫索引好比是一本書前面的目錄,能加快數(shù)據(jù)庫的查詢速度。上述SQL語句,在沒有索引的情況下,數(shù)據(jù)庫會(huì)遍歷全部200條數(shù)據(jù)后選擇符合條件的;而有了相應(yīng)的索引之后,數(shù)據(jù)庫會(huì)直接在索引中查找符合條件的選項(xiàng)。如果我們把SQL語句換成“SELECT * FROM article WHERE id=2000000”,那么你是希望數(shù)據(jù)庫按照順序讀取完200萬行數(shù)據(jù)以后給你結(jié)果還是直接在索引中定位呢?上面的兩個(gè)圖片鮮明的用時(shí)對比已經(jīng)給出了答案(注:一般數(shù)據(jù)庫默認(rèn)都會(huì)為主鍵生成索引)。
索引分為聚簇索引和非聚簇索引兩種,聚簇索引是按照數(shù)據(jù)存放的物理位置為順序的,而非聚簇索引就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對于單行的檢索很快。
索引的類型
1. 普通索引
這是最基本的索引,它沒有任何,比如上文中為title字段創(chuàng)建的索引就是一個(gè)普通索引。
–直接創(chuàng)建索引
CREATE INDEX indexName ON table(column(length))
–修改表結(jié)構(gòu)的方式添加索引
ALTER tableADD INDEX indexName ON (column(length))
–創(chuàng)建表的時(shí)候同時(shí)創(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 indexName (title(length))
)
–刪除索引
DROP INDEX indexName ON table
2. 唯一索引
與普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值(注意和主鍵不同)。如果是組合索引,則列值的組合必須唯一,創(chuàng)建方法和普通索引類似。
–創(chuàng)建唯一索引
CREATE UNIQUE INDEX indexName ON table(column(length))
–修改表結(jié)構(gòu)
ALTER table ADD UNIQUE indexName ON (column(length))
–創(chuàng)建表的時(shí)候直接指定
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ù)集,將你的資料輸入一個(gè)沒有FULLTEXT索引的表中,,然后創(chuàng)建索引,其速度比把資料輸入現(xiàn)有FULLTEXT索引的速度更為快。不過切記對于大容量的數(shù)據(jù)表,生成全文索引是一個(gè)非常消耗時(shí)間非常消耗硬盤空間的做法。
–創(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. 單列索引、多列索引
多個(gè)單列索引與單個(gè)多列索引的查詢效果不同,因?yàn)閳?zhí)行查詢時(shí),MySQL只能使用一個(gè)索引,會(huì)從多個(gè)索引中選擇一個(gè)最為嚴(yán)格的索引。
5. 組合索引(最左前綴)
平時(shí)用的SQL查詢語句一般都有比較多的條件,所以為了進(jìn)一步榨取MySQL的效率,就要考慮建立組合索引。例如上表中針對title和time建立一個(gè)組合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。建立這樣的組合索引,其實(shí)是相當(dāng)于分別建立了下面兩組組合索引:
–title,time
–title
為什么沒有time這樣的組合索引呢?這是因?yàn)镸ySQL組合索引“最左前綴”的結(jié)果。簡單的理解就是只從最左面的開始組合。并不是只要包含這兩列的查詢都會(huì)用到該組合索引,如下面的幾個(gè)SQL所示:
–使用到上面的索引
SELECT * FROM article WHREE title=“PHP程序員” AND time=12345670
SELECT * FROM article WHREE utitle=“PHP程序員”
–不使用上面的索引
SELECT * FROM article WHREE time=12345670
MySQL索引的優(yōu)化
Copyright ? 2019- 91gzw.com 版權(quán)所有 湘ICP備2023023988號-2
違法及侵權(quán)請聯(lián)系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市萬商天勤律師事務(wù)所王興未律師提供法律服務(wù)