■ 利用EXPLAIN 检验优化程式操作。检查用于查询中的索引是否能很快地排除行。假如不能,那么应该试一下利用STRAIGHT_JOIN 强制按特定次序使用表来完成一个连接。查询的执行方式不那么显然;MySQL可能会有很多理由不以您认为最好的次序使用索引。
■ 测试查询的其他形式,而且不止一次地运行他们。在测试一个查询的其他形式时,应该每种方法运行几次。假如对两个不同方法中的每种只运行查询一次,通常会发现第二个查询更快,因为来自第一个查询的信息在磁盘高速缓存中,无需实际从磁盘上读出。还应该尽量在系统负载相对平稳的时候运行查询,以避免受系统中其他活动的影响。
2 忽略优化
这可能听起来有点奇怪,但在以下情况中,要废除MySQL的优化功能:
强迫MySQL慢慢地删除表的内容。在需要完全删空一个表时,利用无WHERE 子句的DELETE 语句删除整个表的内容是最快的,如下所示:
DELETE FROM tb1_name
MySQL对这种特别情况的DELETE 进行优化;他利用表信息文档中的表说明从头开始创建空数据文档和索引文档。这种优化使DELETE 操作极快,因为MySQL无需单独地删除每一行。但在某些情况下,这样做会产生一些不必要的负作用:
■ MySQL报告所涉及的行数为零,即使表不为空也是如此。很多时候这没有关系(虽然,假如事先没有思想准备,会感到困惑不解),但对于那些确实需要知道真实行数的应用程式来说,这是不恰当的。
■ 假如表含有一个AUTO_INCREMENT 列,则该列的顺序编号会以1从头开始。这是真实的事情,即使在MySQL3.23 中对AUTO_INCREMENT 的处理进行了改进后也是这样。关于这个改进的介绍请参阅第2章中的“使用序列”小节。可增加WHERE 1> 0 子句对DELETE 语句“不优化”。
DELETE FROM tb1_name WHERE 1> 0
这迫使MySQL进行逐行的删除。相应的查询执行要慢得多,但将返回真正删除的行数。他还将保持当前的AUTO_INCREMENT 序列的编号,但是只对MyISAM 表(MySQL3.23 以上的版本可用)有效。而对于ISAM 表,序列仍将重置。
■ 避免更新循环不终止。假如更新一个索引列,假如该列用于WHERE 子句且更新将索引值移入至今尚未出超的取值范围内时,有可能对所更新的行进行不终止的更新。假如表my_tbl 有一个索引了的整数列key _ c o l。下列的查询会产生问题:
![]()
这个问题的解决方法是在WHERE 子句中将key_col 用于一个表达式,使MySQL不能使用索引:![]()
实际上,更有另外的方法,即升级到MySQL3.23.2 或更高的版本,他们已解决了这样的问题。
以随机次序检索结果。自MySQL3.23.3 以来,可使用ORDER BY RAND( ) 随机地对结果进行排序。另一技术对MySQL更旧的版本很有用处,那就是选择一个随机数列,然后在该列上进行排序。但是,假如按如下编写查询,优化程式将会让您的愿望落空:![]()
这里的问题是MySQL认为该列是个函数调用,将认为相应的列值是个常数,而对ORDER BY 子句进行优化,使此查询失效。可在表达式中引用某个表列来蒙骗优化程式。例如,假如表中有一个名为age 的列,可编写如下查询:![]()
忽略优化程式的表连接次序。可利用STRIGHT_JOIN 强迫优化程式以特定的次序使用表。假如这样做,应该规定表的次序,使第一个表为从中选择的行数最少的表。(假如不能肯定哪个表满足这个需要,可将行数最多的表作为第一个表。)换句话说,应尽量规定表的次序,使最有限制性的选择先出现。排除可能的候选行越早,查询执行得就越快。要确保测试相应的查询两次;可能会有某些原因使优化程式不以您所想像的方式对表进行连接,并且STRAIGHT_JOIN 也可能实际上不起作用。
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




