MySQL 性能优化的 21 个最佳实践( 四 )


另外,你需要注意的是,这些被分出去的字段所形成的表,你不会经常性地去 Join 他们,不然的话,这样的性能会比不分割时还要差,而且,会是极数级的下降 。
17.拆分大的 DELETE 或 INSERT 语句
如果你需要在一个在线的网站上去执行一个大的 DELETE 或 INSERT 查询,你需要非常小心,要避免你的操作让你的整个网站停止相应 。因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了 。
Apache 会有很多的子进程或线程 。所以,其工作起来相当有效率,而我们的服务器也不希望有太多的子进程,线程和数据库链接,这是极大的占服务器资源的事情,尤其是内存 。
如果你把你的表锁上一段时间,比如 30 秒钟,那么对于一个有很高访问量的站点来说,这 30 秒所积累的访问进程/线程,数据库链接,打开的文件数,可能不仅仅会让你泊 WEB 服务 Crash,还可能会让你的整台服务器马上掛了 。
所以,如果你有一个大的处理,你定你一定把其拆分,使用 LIMIT 条件是一个好的方法 。下面是一个示例:

MySQL 性能优化的 21 个最佳实践

文章插图
 
18.越小的列会越快
对于大多数的数据库引擎来说,硬盘操作可能是最重大的瓶颈 。所以,把你的数据变得紧凑会对这种情况非常有帮助,因为这减少了对硬盘的访问 。
参看 MySQL 的文档 Storage Requirements 查看所有的数据类型 。
如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理由使用 INT 来做主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些 。如果你不需要记录时间,使用 DATE 要比 DATETIME 好得多 。
当然,你也需要留够足够的扩展空间,不然,你日后来干这个事,你会死的很难看,参看 Slashdot 的例子(2009 年 11 月 06 日),一个简单的 ALTER TABLE 语句花了 3 个多小时,因为里面有一千六百万条数据 。
19.选择正确的存储引擎
在 MySQL 中有两个存储引擎 MyISAM 和 InnoDB,每个引擎都有利有弊 。酷壳以前文章《MySQL: InnoDB 还是 MyISAM?》讨论和这个事情 。
MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好 。甚至你只是需要 update 一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成 。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的 。
InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比MyISAM 还慢 。他是它支持“行锁”,于是在写操作比较多的时候,会更优秀 。并且,他还支持更多的高级应用,比如:事务 。
下面是 MySQL 的手册
target=”_blank”MyISAM Storage Engine InnoDB Storage Engine 20.使用一个对象关系映射器(Object Relational Mapper)
使用 ORM (Object Relational Mapper),你能够获得可靠的性能增涨 。一个
ORM 可以做的所有事情,也能被手动的编写出来 。但是,这需要一个高级专家 。
ORM 的最重要的是“Lazy Loading”,也就是说,只有在需要的去取值的时候才会去真正的去做 。但你也需要小心这种机制的副作用,因为这很有可能会因为要去创建很多很多小的查询反而会降低性能 。
ORM 还可以把你的 SQL 语句打包成一个事务,这会比单独执行他们快得多得多 。
目前,个人最喜欢的 PHP 的 ORM 是:Doctrine 。
21.小心“永久链接”
“永久链接”的目的是用来减少重新创建 MySQL 链接的次数 。当一个链接被创建了,它会永远处在连接的状态,就算是数据库操作已经结束了 。而且,自从我们的 Apache 开始重用它的子进程后——也就是说,下一次的 HTTP 请求会重用 Apache 的子进程,并重用相同的 MySQL 链接 。
PHP 手册:mysql_pconnect()
在理论上来说,这听起来非常的不错 。但是从个人经验(也是大多数人的) 上来说,这个功能制造出来的麻烦事更多 。因为,你只有有限的链接数,内存问题,文件句柄数,等等 。
而且,Apache 运行在极端并行的环境中,会创建很多很多的了进程 。这就是为什么这种“永久链接”的机制工作地不好的原因 。在你决定要使用“永久链接”之前,你需要好好地考虑一下你的整个系统的架构 。




推荐阅读