大多數(shù)的 MySQL 服務(wù)器都開啟了查詢緩存。這是提高性最有效的方法之一,而且這是被 MySQL 的數(shù)據(jù)庫引擎處理的。當(dāng)有很多相同的查詢被執(zhí)行了多次的時(shí)候,這些查詢結(jié)果會(huì)被放到一個(gè)緩存中,這樣,后續(xù)的相同的查詢就不用操作表而直接訪問緩存結(jié)果了。
這里最主要的問題是,對(duì)于程序員來說,這個(gè)事情是很容易被忽略的。因?yàn)椋覀兡承┎樵冋Z句會(huì)讓 MySQL 不使用緩存。請(qǐng)看下面的示例:
從上圖你可以看到那個(gè)搜索字串 “last_name LIKE ‘a%’”,一個(gè)是建了索引,一個(gè)是沒有索引,性能差了 4 倍左右。
另外,你應(yīng)該也需要知道什么樣的搜索是不能使用正常的索引的。例如,當(dāng)你需要在一篇大的文章中搜索一個(gè)詞時(shí),如: “WHERE post_content LIKE ‘%apple%’”,索引可能是沒有意義的。你可能需要使用 MySQL 全文索引 或是自己做一個(gè)索引(比如說:搜索關(guān)鍵詞或是 Tag 什么的)
如果你真的想把返回的數(shù)據(jù)行打亂了,你有 N 種方法可以達(dá)到這個(gè)目的。這樣使用只讓你的數(shù)據(jù)庫的性能呈指數(shù)級(jí)的下降。這里的問題是:MySQL 會(huì)不得不去執(zhí)行 RAND()函數(shù)(很耗 CPU 時(shí)間),而且這是為了每一行記錄去記行,然后再對(duì)其排序。就算是你用了 Limit 1 也無濟(jì)于事(因?yàn)橐判?
下面的示例是隨機(jī)挑一條記錄: 7.避免 SELECT *
從數(shù)據(jù)庫里讀出越多的數(shù)據(jù),那么查詢就會(huì)變得越慢。并且,如果你的數(shù)據(jù)庫服務(wù)器和 WEB 服務(wù)器是兩臺(tái)獨(dú)立的服務(wù)器的話,這還會(huì)增加網(wǎng)絡(luò)傳輸?shù)呢?fù)載。所以,你應(yīng)該養(yǎng)成一個(gè)需要什么就取什么的好的習(xí)慣。
8. 永遠(yuǎn)為每張表設(shè)置一個(gè) ID
我們應(yīng)該為數(shù)據(jù)庫里的每張表都設(shè)置一個(gè) ID 做為其主鍵,而且最好的是一個(gè) INT 型的(推薦使用 UNSIGNED),并設(shè)置上自動(dòng)增加的 AUTO_INCREMENT 標(biāo)志。
就算是你 users 表有一個(gè)主鍵叫 “email”的字段,你也別讓它成為主鍵。使用 VARCHAR 類型來當(dāng)主鍵會(huì)使用得性能下降。另外,在你的程序中,你應(yīng)該使用表的 ID 來構(gòu)造你的數(shù)據(jù)結(jié)構(gòu)。
而且,在 MySQL 數(shù)據(jù)引擎下,還有一些操作需要使用主鍵,在這些情況下,主鍵的性能和設(shè)置變得非常重要,比如,集群,分區(qū)……
在這里,只有一個(gè)情況是例外,那就是“關(guān)聯(lián)表”的“外鍵”,也就是說,這個(gè)表的主鍵,通過若干個(gè)別的表的主鍵構(gòu)成。我們把這個(gè)情況叫做“外鍵”。比如:有一個(gè)“學(xué)生表”有學(xué)生的 ID,有一個(gè)“課程表”有課程 ID,那么,“成績表”就是“關(guān)聯(lián)表”了,其關(guān)聯(lián)了學(xué)生表和課程表,在成績表中,學(xué)生 ID 和課程 ID 叫“外鍵”其共同組成主鍵。
MySQL 也有一個(gè)“建議”(見第十條)告訴你怎么去重新組織你的表結(jié)構(gòu)。當(dāng)你有一個(gè) VARCHAR 字段時(shí),這個(gè)建議會(huì)告訴你把其改成 ENUM 類型。使用PROCEDURE ANALYSE() 你可以得到相關(guān)的建議
10. 從 PROCEDURE ANALYSE() 取得建議
PROCEDURE ANALYSE() 會(huì)讓 MySQL 幫你去分析你的字段和其實(shí)際的數(shù)據(jù),并會(huì)給你一些有用的建議。只有表中有實(shí)際的數(shù)據(jù),這些建議才會(huì)變得有用,因?yàn)橐鲆恍┐蟮臎Q定是需要有數(shù)據(jù)作為基礎(chǔ)的。
例如,如果你創(chuàng)建了一個(gè) INT 字段作為你的主鍵,然而并沒有太多的數(shù)據(jù),那么,PROCEDURE ANALYSE()會(huì)建議你把這個(gè)字段的類型改成 MEDIUMINT 。或是你使用了一個(gè) VARCHAR 字段,因?yàn)閿?shù)據(jù)不多,你可能會(huì)得到一個(gè)讓你把它
很多程序員都會(huì)創(chuàng)建一個(gè) VARCHAR(15) 字段來存放字符串形式的 IP 而不是整形的 IP。如果你用整形來存放,只需要 4 個(gè)字節(jié),并且你可以有定長的字段。而且,這會(huì)為你帶來查詢上的優(yōu)勢,尤其是當(dāng)你需要使用這樣的 WHERE 條件:IP between ip1 and ip2。