今天我想對一個Greenfield項目上能夠採用的各類性能優化策略做個對比。換言之,該項目沒有以前決策強加給它的各類約束限制,也尚未被優化過。html
具體來講,我想比較的兩種優化策略是優化MySQL和緩存。提早指出,這些優化是正交的,惟一讓你選擇其中一者而不是另外一者的緣由是他們都耗費了資源,即開發時間。前端
優化MySQL時,通常會先查看發送給mysql的查詢語句,而後運行explain命令。稍加審查後很常見的作法是增長索引或者對模式作一些調整。mysql
一、一個通過優化的查詢對於全部使用應用的用戶來講都是快速的。由於索引經過對數複雜度的速度來檢索數據(又名分制,正如你搜索一個電話簿同樣,逐步縮小搜索範圍),並且隨着數據量的遞增也能維持良好的性能。對一個未經索引化的查詢的結果作緩存隨着數據的增加有時候則可能會表現得更差。隨着數據的增加,那些未命中緩存的用戶可能會獲得很糟糕的體驗,這樣的應用是不可用的。sql
二、優化MySQL不須要擔憂緩存失效或者緩存數據過時的問題。數據庫
三、優化MySQL能夠簡化技術架構,在開發環境下複製和工做會更加容易。緩存
一、有一些查詢不能光經過索引獲得性能上的改善,可能還須要改變模式,在某些狀況下這對於一些應用可能會很麻煩。性能優化
二、有些模式的更改可能用於反規範化(數據備份)。儘管對於DBA來講,這是一項經常使用的技術,它須要全部權以確保全部的地方都是由應用程序更新,或須要安裝觸發器來保證這種變化。服務器
三、一些優化手段多是MySQL所特有的。也就是說,若是底層軟件被移植到多個數據庫上工做,那麼很難確保除了增長索引外一些更復雜的優化技術能夠通用。架構
這種優化須要人來分析應用的實際狀況,而後將處理代價昂貴的部分從MySQL中剝離出來用第三方緩存替代,好比memcached或Redis。memcached
一、緩存對於一些MySql自身很難優化的查詢來講會工做地很好,好比大規模的聚合或者分組的查詢。
二、緩存對於提升系統的吞吐率來講多是個不錯的方案。好比對於多人同時訪問應用時響應速度很慢的狀況。
三、緩存可能更容易構建在另外一個應用之上。好比:你的應用多是另外一個用MySQL存儲數據的軟件包的前端,而要對這個軟件包作任何數據庫方面的改動都很是難。
一、若是數據對外提供多種存取範式(例如,在不一樣的頁面上用不一樣的形式展現),那麼讓緩存過時或者更新可能會很難,同時/或者可能須要容忍已過時的數據。一個可行的替代方案是設計一套更加精細的緩存機制,固然它也有缺點,即屢次獲取緩存會增長時延。
二、緩存一個產生代價昂貴的對象對於那些未命中緩存的用戶(見優化MySQL的優點#1)而言可能會產生潛在的性能差別。一些好的性能實踐代表你應該儘可能縮小用戶之間的差別性,而不只僅是平均化(緩存傾向於這麼作)。
三、幼稚的緩存實現無力應對一些微妙的漏洞,好比雪崩效應。就在上週我幫助了一我的,他的數據庫服務器被多個試圖同時再生一樣緩存內容的用戶請求沖垮。正確的策略是引入必定級別的鎖來將緩存再生的請求序列化。
通常狀況下,我會建議用戶先對MySQL進行優化,由於這是我認爲開始階段最合適的解決方案。但長期來看,大部分應用都會有一些用例須要必定程度上同時實現以上這些方案。
原文連接: Morgan Tocker