PHPCMS开发文档里看到PHP编码规范
2009-10-17 05:33:00 来源:WEB开发网5.3.3. 结构优化与索引优化
索引能加快查询速度,而索引优化和查询优化是相辅相成的,既可以依据查询对索引进行优化,也可以依据现有索引对查询进行优化,这取决于修改查询或索引,哪个对现有产品架构和效率的影响最小。
索引优化与查询优化是多年经验积累的结晶,在此无法详述,但仍然给出几条最基本的准则。
首先,根据产品的实际运行和被访问情况,找出哪些SQL语句是最常被执行的。最常被执行和最常出现在程序中是完全不同的概念。最常被执行的SQL语句,又可被划分为对大表(数据条目多的)和对小表(数据条目少的)的操作。无论大表或小表,有可分为读(SELECT)多、写(UPDATE/INSERT)多或读写都多的操作。
对常被执行的SQL语句而言,对大表操作需要尤其注意:
l 写操作多的,通常可使用写入缓存的方法,先将需要写或需要更新的数据缓存至文件或其他表,定期对大表进行批量写操作。同时,应尽量使得常被读写的大表为定长类型,即便原本的结构中大表并非定长。大表定长化,可以通过改变数据存储结构和数据读取方式,将一个大表拆成一个读写多的定长表,和一个读多写少的变长表来实现;
l 读操作多的,需要依据SQL查询频率设置专门针对高频SQL语句的索引和联合索引。
而小表就相对简单,加入符合查询要求的特定索引,通常效果比较明显。同时,定长化小表也有益于效率和负载能力的提高。字段比较少的小定长表,甚至可以不需要索引。
其次,看SQL语句的条件和排序字段是否动态性很高(即根据不同功能开关或属性,SQL查询条件和排序字段的变化很大的情况),动态性过高的SQL语句是无法通过索引进行优化的。惟一的办法只有将数据缓存起来,定期更新,适用于结果对实效性要求不高的场合。
MySQL索引,常用的有PRIMARY KEY、INDEX、UNIQUE几种,详情请查阅MySQL文档。通常,在单表数据值不重复的情况下,PRIMARY KEY和UNIQUE索引比INDEX更快,请酌情使用。
事实上,索引是将条件查询、排序的读操作资源消耗,分布到了写操作中,索引越多,耗费磁盘空间越大,写操作越慢。因此,索引决不能盲目添加。对字段索引与否,最根本的出发点,依次仍然是SQL语句执行的概率、表的大小和写操作的频繁程度。
5.3.4. 查询优化
MySQL中并没有提供针对查询条件的优化功能,因此需要开发者在程序中对查询条件的先后顺序人工进行优化。例如如下的SQL语句:
SELECT * FROM table WHERE a>’0’ AND b<’1’ ORDER BY c LIMIT 10;
事实上无论a>’0’还是b<’1’哪个条件在前,得到的结果都是一样的,但查询速度就大不相同,尤其在对大表进行操作时。
开发者需要牢记这个原则:最先出现的条件,一定是过滤和排除掉更多结果的条件;第二出现的次之;以此类推。因而,表中不同字段的值的分布,对查询速度有着很大影响。而ORDER BY中的条件,只与索引有关,与条件顺序无关。
除了条件顺序优化以外,针对固定或相对固定的SQL查询语句,还可以通过对索引结构进行优化,进而实现相当高的查询速度。原则是:在大多数情况下,根据WHERE条件的先后顺序和ORDER BY的排序字段的先后顺序而建立的联合索引,就是与这条SQL语句匹配的最优索引结构。尽管,事实的产品中不能只考虑一条SQL语句,也不能不考虑空间占用而建立太多的索引。
同样以上面的SQL语句为例,最优的当table表的记录达到百万甚至千万级后,可以明显的看到索引优化带来的速度提升。
依据上面条件优化和索引优化的两个原则,当table表的值为如下方案时,可以得出最优的条件顺序方案:
字段a 字段b 字段c
1 7 11
2 8 10
3 9 13
-1 0 12
最优条件:b<’1’ AND a>’0’
最优索引:INDEX abc (b, a, c)
原因:b<’1’作为第一条件可以先过滤掉75%的结果。如果以a>’0’作为第一条件,则只能先过滤掉25%的结果
注意1:字段c由于未出现于条件中,故条件顺序优化与其无关
注意2:最优索引由最优条件顺序得来,而非由例子中的SQL语句得来
注意3:索引并非修改数据存储的物理顺序,而是通过对应特定偏移量的物理数据而实现的虚拟指针
EXPLAIN语句是检测索引和查询能否良好匹配的简便方法。在phpMyAdmin或其他MySQL客户端中运行EXPLAIN+查询语句,例如EXPLAIN select * FROM table WHERE a>’0’ AND b<’1’ ORDER BY c;这种形式,即使得开发者无需模拟上百万条数据,也可以验证索引是否合理,相关细节请参考MySQL说明。
值得提出的是,Using filesort是最不应当出现的情况,如果EXPLAIN得出此结果,说明数据库为这个查询专门建立了一个用以缓存结果的临时表文件,并在查询结束后删除。众所周知,硬盘I/O速度始终是计算机存储的瓶颈,因此,查询中应当尽全力避免高执行频率的SQL语句使用filesort。尽管,开发者永远都不可能保证产品中的全部SQL语句都不会使用filesort。
限于篇幅,本文档远远没有涵盖数据库优化的方方面面,例如:联合索引与普通索引的可重用性、JOIN连接的索引设计、MEMORY/HEAP表等。数据库优化实际上就是在很多因素和利弊间不断权衡、修改,惟有在成功与失败经验中反复推敲才能得出的经验,这种经验往往就是最难能可贵和价值连城的。
5.3.5. 兼容性问题
由于MySQL 3.23至5.0的变化很大,因此程序中尽量不使用特殊的SQL语句,以免带来兼容性问题,并给数据库移植造成困难。
通常在MySQL 4.1以上版本,phpcms应使用相当的字符集来存储,例如GBK/BIG5/UTF-8。传统的latin1编码虽然有一定的兼容性,但仍然不是推荐的选择。使用相应非默认字符集时,程序每次运行时需要使用SET NAMES ‘character_set’;来规定连接、传输和结果的字符集。
Mysql 5.0以上新增了数种SQL_MODE,默认的SQL_MODE依服务器安装设置不同而不同,因此程序每次运行时需要使用SET SQL_MODE=’’;来规定当前的SQL模式。
- ››开发学院教你用SQL 语句最快速清空MySQL 数据表的...
- ››开发一个自己的HTML在线编辑器(一)
- ››开发一个自己的HTML在线编辑器(二)
- ››开发者在App Store上赚的钱比在Android Market上多...
- ››开发者应深入学习的10个Android开源应用项目
- ››开发移动 Web Ajax 应用
- ››开发者眼中的iPhone与Android
- ››Phpcms2008个性化利器-万能GET标签使用完全教程
- ››PHPCMS网站验证码不显示的解决方法
- ››phpcms提示您已经被管理员禁止访问
- ››开发者或想使用的10个Android2.2新特性
- ››开发实例:Android 身高计算器的实现
更多精彩
赞助商链接