MySQL查询优化程序
2006-04-07 10:45:38 来源:WEB开发网还假定,与col1上的测试相符的有900 行,与col2 上的测试相符的有300 行,而两个测试都通过的有30 行。如果首先测试c o l 1,必须检查900 行以找到也与col2 值相符的30 行。那么测试中有870 将失败。如果首先测试c o l 2,要找到也与col1值相符的30 行,只需检查300 行。测试中有失败270 次,这样所涉及的计算较少,磁盘I/O 也较少。遵循下列准则,有助于优化程序利用索引:
1 比较具有相同类型的列。在比较中利用索引列时,应该使用那些类型相同的列。例如,CHAR(10) 被视为与CHAR(10) 或VARCHAR(10) 相同,但不同于CHAR(12) 和VARCHAR( 12 )。INT 与BIGINT 不同。在MySQL3.23 版以前,要求使用相同类型的列,否则列上的索引将不起作用。自3.23 版后,不严格要求这样做,但相同的列类型比不同类型提供更好的性能。如果所比较的两列类型不同,可使用ALTER TABLE语句修改其中之一使它们的类型相配。
2 比较中应尽量使索引列独立。如果在函数调用或算术表达式中使用一个列,则MySQL不能使用这样的索引,因为它必须对每行计算表达式的值。有时,这是不可避免的,但很多时候,可以重新编写只取索引列本身的查询。下面的WHERE 子句说明了怎样进行这项工作。第一行中,优化程序将简化表达式4/2 为值2,然后使用my_col 上的索引快速地找到小于2 的值。而在第二个表达式中,MySQL必须检索出每行的my_col 值,乘以2,然后将结果与4 比较。没索引可用,因为列中的每个值都要检索,以便能对左边的表达式求值:
WHERE my_col < 4/2
WHERE my_col * 2 < 4
让我们考虑另一个例子。假如有一个索引列date _ c o l。如果发布如下的查询,相应的索引未被使用:
SELECT * FROM my_tb1WHERE YEAR(date_col) < 1990
其中表达式并不将索引列与1990 比较,而是将从列值计算出的值用于比较,而且必须计算每行的这个值。结果是, date_col 上的索引不可能得到使用。怎样解决?使用一个文字日期即可,这时将会使用date_col 上的索引:
WHERE date_col < "1990-01-01"
但是假如没有特定的日期值,那么可能会对找到具有出现在距今一定天数内的日期的记录感兴趣。有几种方法来编写这样的查询,但并非所有方法都很好。三种可能的方法如下:
其中第一行不能利用索引, 因为必须为每行检索列, 以便能够计算TO _ DAYS(date_col) 的值。第二行要好一些。c ut o ff 和TO _ DAY S ( CURRENT _ DATE) 两者都是常量,因此比较表达式的右边可在查询处理前由优化程序一次计算出来,而不是每行计算一次。但date_col 列仍然出现在一个函数调用中,因此,没有使用索引。第三行是最好的方法。比较表达式的右边可在执行查询前作为常量一次计算出来,但现在其值是一个日期。这个值可直接与date_col 的值进行比较,不再需要转换为天数,可以利用索引。
更多精彩
赞助商链接