1. 為查詢緩存優(yōu)化你的查詢
大多數(shù)的MySQL服務(wù)器都開啟了查詢緩存练对。這是提高性最有效的方法之一,而且這是被MySQL的數(shù)據(jù)庫(kù)引擎處理的栅哀。當(dāng)有很多相同的查詢被執(zhí)行了多次的時(shí)候滥壕,這些查詢結(jié)果會(huì)被放到一個(gè)緩存中,這樣绍绘,后續(xù)的相同的查詢就不用操作表而直接訪問(wèn)緩存結(jié)果了。
像 NOW() 和 RAND() 或是其它的諸如此類的SQL函數(shù)都不會(huì)開啟查詢緩存,因?yàn)檫@些函數(shù)的返回是會(huì)不定的易變的陪拘。所以厂镇,你所需要的就是用一個(gè)變量來(lái)代替MySQL的函數(shù),從而開啟緩存左刽。
2. EXPLAIN 你的 SELECT 查詢
使用 EXPLAIN 關(guān)鍵字可以讓你知道MySQL是如何處理你的SQL語(yǔ)句的捺信。這可以幫你分析你的查詢語(yǔ)句或是表結(jié)構(gòu)的性能瓶頸。
EXPLAIN 的查詢結(jié)果還會(huì)告訴你你的索引主鍵被如何利用的欠痴,你的數(shù)據(jù)表是如何被搜索和排序的……等等迄靠,等等。
3. 當(dāng)只要一行數(shù)據(jù)時(shí)使用 LIMIT 1
當(dāng)你查詢表的有些時(shí)候喇辽,你已經(jīng)知道結(jié)果只會(huì)有一條結(jié)果掌挚,但因?yàn)槟憧赡苄枰etch游標(biāo),或是你也許會(huì)去檢查返回的記錄數(shù)菩咨。
在這種情況下吠式,加上 LIMIT 1 可以增加性能。這樣一樣旦委,MySQL數(shù)據(jù)庫(kù)引擎會(huì)在找到一條數(shù)據(jù)后停止搜索奇徒,而不是繼續(xù)往后查少下一條符合記錄的數(shù)據(jù)。
4. 為搜索字段建索引
索引并不一定就是給主鍵或是唯一的字段缨硝。如果在你的表中,有某個(gè)字段你總要會(huì)經(jīng)常用來(lái)做搜索罢低,那么查辩,請(qǐng)為其建立索引吧。
**5. 在Join表的時(shí)候使用相當(dāng)類型的例网持,并將其索引 **
如果你的應(yīng)用程序有很多 JOIN 查詢宜岛,你應(yīng)該確認(rèn)兩個(gè)表中Join的字段是被建過(guò)索引的。這樣功舀,MySQL內(nèi)部會(huì)啟動(dòng)為你優(yōu)化Join的SQL語(yǔ)句的機(jī)制萍倡。
而且,這些被用來(lái)Join的字段辟汰,應(yīng)該是相同的類型的列敲。例如:如果你要把 DECIMAL 字段和一個(gè) INT 字段Join在一起,MySQL就無(wú)法使用它們的索引帖汞。對(duì)于那些STRING類型戴而,還需要有相同的字符集才行。
6. 千萬(wàn)不要 ORDER BY RAND()
MySQL執(zhí)行RAND()函數(shù)很耗CPU時(shí)間
**7. 避免 SELECT * **
8. 永遠(yuǎn)為每張表設(shè)置一個(gè)ID
只有一個(gè)情況是例外翩蘸,那就是“關(guān)聯(lián)表”的“外鍵”所意,也就是說(shuō),這個(gè)表的主鍵,通過(guò)若干個(gè)別的表的主鍵構(gòu)成扶踊。我們把這個(gè)情況叫做“外鍵”泄鹏。
9. 使用 ENUM 而不是 VARCHAR
ENUM 類型是非常快和緊湊的秧耗。在實(shí)際上命满,其保存的是 TINYINT,但其外表上顯示為字符串绣版。這樣一來(lái)胶台,用這個(gè)字段來(lái)做一些選項(xiàng)列表變得相當(dāng)?shù)耐昝馈?br>
如果你有一個(gè)字段,比如“性別”杂抽,“國(guó)家”诈唬,“民族”,“狀態(tài)”或“部門”缩麸,你知道這些字段的取值是有限而且固定的铸磅,那么,你應(yīng)該使用 ENUM 而不是 VARCHAR杭朱。
**10. 從 PROCEDURE ANALYSE() 取得建議 **
PROCEDURE ANALYSE() 會(huì)讓 MySQL 幫你去分析你的字段和其實(shí)際的數(shù)據(jù)阅仔,并會(huì)給你一些有用的建議。只有表中有實(shí)際的數(shù)據(jù)弧械,這些建議才會(huì)變得有用八酒,因?yàn)橐鲆恍┐蟮臎Q定是需要有數(shù)據(jù)作為基礎(chǔ)的。
11. 盡可能的使用 NOT NULL
對(duì)于那些類型要求嚴(yán)格的語(yǔ)言來(lái)說(shuō)非常重要
**12. 無(wú)緩沖的查詢 **
mysql_unbuffered_query()可以實(shí)現(xiàn)無(wú)緩沖查詢刃唐,大數(shù)據(jù)的情況下非常有用羞迷,可以節(jié)約內(nèi)存
13. 把IP地址存成 UNSIGNED INT
14. 固定長(zhǎng)度的表會(huì)更快
15. 垂直分割
“垂直分割”是一種把數(shù)據(jù)庫(kù)中的表按列變成幾張表的方法,這樣可以降低表的復(fù)雜度和字段的數(shù)目画饥,從而達(dá)到優(yōu)化的目的衔瓮。
**16. 拆分大的 DELETE 或 INSERT 語(yǔ)句 **
如果你需要在一個(gè)在線的網(wǎng)站上去執(zhí)行一個(gè)大的 DELETE 或 INSERT 查詢,你需要非常小心抖甘,要避免你的操作讓你的整個(gè)網(wǎng)站停止相應(yīng)热鞍。因?yàn)檫@兩個(gè)操作是會(huì)鎖表的,表一鎖住了衔彻,別的操作都進(jìn)不來(lái)了薇宠。
17. 越小的列會(huì)越快
對(duì)于大多數(shù)的數(shù)據(jù)庫(kù)引擎來(lái)說(shuō),硬盤操作可能是最重大的瓶頸米奸。所以昼接,把你的數(shù)據(jù)變得緊湊會(huì)對(duì)這種情況非常有幫助,因?yàn)檫@減少了對(duì)硬盤的訪問(wèn)悴晰。
*18. 選擇正確的存儲(chǔ)引擎 **
在 MySQL 中有兩個(gè)存儲(chǔ)引擎 MyISAM 和 InnoDB慢睡,每個(gè)引擎都有利有弊逐工。
MyISAM 適合于一些需要大量查詢的應(yīng)用,但其對(duì)于有大量寫操作并不是很好漂辐。甚至你只是需要update一個(gè)字段泪喊,整個(gè)表都會(huì)被鎖起來(lái),而別的進(jìn)程髓涯,就算是讀進(jìn)程都無(wú)法操作直到讀操作完成袒啼。另外,MyISAM 對(duì)于 SELECT COUNT() 這類的計(jì)算是超快無(wú)比的纬纪。
InnoDB 的趨勢(shì)會(huì)是一個(gè)非常復(fù)雜的存儲(chǔ)引擎蚓再,對(duì)于一些小的應(yīng)用,它會(huì)比 MyISAM 還慢包各。他是它支持“行鎖” 摘仅,于是在寫操作比較多的時(shí)候,會(huì)更優(yōu)秀问畅。并且娃属,他還支持更多的高級(jí)應(yīng)用,比如:事務(wù)护姆。
19. 使用一個(gè)對(duì)象關(guān)系映射器(Object Relational Mapper)
使用 ORM (Object Relational Mapper)矾端,你能夠獲得可靠的性能增漲。一個(gè)ORM可以做的所有事情卵皂,也能被手動(dòng)的編寫出來(lái)秩铆。但是,這需要一個(gè)高級(jí)專家渐裂。ORM 的最重要的是“Lazy Loading”豺旬,也就是說(shuō),只有在需要的去取值的時(shí)候才會(huì)去真正的去做柒凉。但你也需要小心這種機(jī)制的副作用,因?yàn)檫@很有可能會(huì)因?yàn)橐?chuàng)建很多很多小的查詢反而會(huì)降低性能篓跛。ORM 還可以把你的SQL語(yǔ)句打包成一個(gè)事務(wù)膝捞,這會(huì)比單獨(dú)執(zhí)行他們快得多得多。