今天我想对一个Greenfield项目上能够采用的各类性能优化策略做个对比。换言之,该项目没有以前决策强加给它的各类约束限制,也尚未被优化过。html
具体来讲,我想比较的两种优化策略是优化MySQL和缓存。提早指出,这些优化是正交的,惟一让你选择其中一者而不是另外一者的缘由是他们都耗费了资源,即开发时间。前端
优化MySQL时,通常会先查看发送给mysql的查询语句,而后运行explain命令。稍加审查后很常见的作法是增长索引或者对模式作一些调整。mysql
一、一个通过优化的查询对于全部使用应用的用户来讲都是快速的。由于索引经过对数复杂度的速度来检索数据(又名分制,正如你搜索一个电话簿同样,逐步缩小搜索范围),并且随着数据量的递增也能维持良好的性能。对一个未经索引化的查询的结果作缓存随着数据的增加有时候则可能会表现得更差。随着数据的增加,那些未命中缓存的用户可能会获得很糟糕的体验,这样的应用是不可用的。sql
二、优化MySQL不须要担忧缓存失效或者缓存数据过时的问题。数据库
三、优化MySQL能够简化技术架构,在开发环境下复制和工做会更加容易。缓存
一、有一些查询不能光经过索引获得性能上的改善,可能还须要改变模式,在某些状况下这对于一些应用可能会很麻烦。性能优化
二、有些模式的更改可能用于反规范化(数据备份)。尽管对于DBA来讲,这是一项经常使用的技术,它须要全部权以确保全部的地方都是由应用程序更新,或须要安装触发器来保证这种变化。服务器
三、一些优化手段多是MySQL所特有的。也就是说,若是底层软件被移植到多个数据库上工做,那么很难确保除了增长索引外一些更复杂的优化技术能够通用。架构
这种优化须要人来分析应用的实际状况,而后将处理代价昂贵的部分从MySQL中剥离出来用第三方缓存替代,好比memcached或Redis。memcached
一、缓存对于一些MySql自身很难优化的查询来讲会工做地很好,好比大规模的聚合或者分组的查询。
二、缓存对于提升系统的吞吐率来讲多是个不错的方案。好比对于多人同时访问应用时响应速度很慢的状况。
三、缓存可能更容易构建在另外一个应用之上。好比:你的应用多是另外一个用MySQL存储数据的软件包的前端,而要对这个软件包作任何数据库方面的改动都很是难。
一、若是数据对外提供多种存取范式(例如,在不一样的页面上用不一样的形式展现),那么让缓存过时或者更新可能会很难,同时/或者可能须要容忍已过时的数据。一个可行的替代方案是设计一套更加精细的缓存机制,固然它也有缺点,即屡次获取缓存会增长时延。
二、缓存一个产生代价昂贵的对象对于那些未命中缓存的用户(见优化MySQL的优点#1)而言可能会产生潜在的性能差别。一些好的性能实践代表你应该尽可能缩小用户之间的差别性,而不只仅是平均化(缓存倾向于这么作)。
三、幼稚的缓存实现无力应对一些微妙的漏洞,好比雪崩效应。就在上周我帮助了一我的,他的数据库服务器被多个试图同时再生一样缓存内容的用户请求冲垮。正确的策略是引入必定级别的锁来将缓存再生的请求序列化。
通常状况下,我会建议用户先对MySQL进行优化,由于这是我认为开始阶段最合适的解决方案。但长期来看,大部分应用都会有一些用例须要必定程度上同时实现以上这些方案。
原文连接: Morgan Tocker