MySQL手册版本 5.0.20-MySQL优化(三) (3)
时间:2008-05-10 来源:sdccf
来源:MySQL手册版本 5.0.20 作者:译者:叶金荣 |
7.2.5 MySQL 如何优化 OR 子句 Index Merge 方法用于使用 ref, ref_or_null, 或 range 扫描取得的记录合并起来放到一起作为结果。这种方法在表条件是或条件 ref, ref_or_null, 或 range ,并且这些条件可以用不同的键时采用。 "join"类型的优化是从 MySQL 5.0.0 开始才有的,代表者在索引的性能上有着标志性的改进,因为使用老规则的话,数据库最多只能对每个引用表使用一个索引。 在 EXPLAIN 的结果中,这种方法在 type 字段中表现为 index_merge。这种情况下,key 字段包含了所有使用的索引列表,并且 key_len 字段包含了使用的索引的最长索引部分列表。 例如: SELECT * FROM tbl_name WHERE key_part1 = 10 OR key_part2 = 20; SELECT * FROM tbl_name WHERE (key_part1 = 10 OR key_part2 = 20) AND non_key_part=30; SELECT * FROM t1,t2 WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%') AND t2.key1=t1.some_col; SELECT * FROM t1,t2 WHERE t1.key1=1 AND (t2.key1=t1.some_col OR t2.key2=t1.some_col2); 7.2.6 MySQL 如何优化 IS NULL MySQL在 col_name IS NULL 时做和 col_name = constant_value 一样的优化。例如,MySQL使用索引或者范围来根据 IS NUL L搜索 NULL。 SELECT * FROM tbl_name WHERE key_col IS NULL; SELECT * FROM tbl_name WHERE key_col <=> NULL; SELECT * FROM tbl_name WHERE key_col=const1 OR key_col=const2 OR key_col IS NULL; 如果一个 WHERE 子句包括了一个 col_name IS NULL 条件,并且这个字段声明为 NOT NULL,那么这个表达式就会被优化。当字段可能无论如何都会产生 NULL 值时,就不会再做优化了;例如,当它来自一个 LEFT JOIN 中右边的一个表时。 MySQL 4.1.1或更高会对连接 col_name = expr AND col_name IS NULL 做额外的优化, 常见的就是子查询。EXPLAIN 当优化起作用时会显示 ref_or_null。 优化程序会为任何索引部分处理 IS NULL。 以下几个例子中都做优化了,假使字段 a 和 表 t2 中 b 有索引了: SELECT * FROM t1 WHERE t1.a=expr OR t1.a IS NULL; SELECT * FROM t1,t2 WHERE t1.a=t2.a OR t2.a IS NULL; SELECT * FROM t1,t2 WHERE (t1.a=t2.a OR t2.a IS NULL) AND t2.b=t1.b; SELECT * FROM t1,t2 WHERE t1.a=t2.a AND (t2.b=t1.b OR t2.b IS NULL); SELECT * FROM t1,t2 WHERE (t1.a=t2.a AND t2.a IS NULL AND ...) OR (t1.a=t2.a AND t2.a IS NULL AND ...); ref_or_null 首先读取引用键,然后独立扫描键值为 NULL 的记录。 请注意,优化程序只会处理一个 IS NULL 级别。下面的查询中,MySQL只会使用键来查询表达式 (t1.a=t2.a AND t2.a IS NULL) 而无法使在 b 上使用索引部分: SELECT * FROM t1,t2 WHERE (t1.a=t2.a AND t2.a IS NULL) OR (t1.b=t2.b AND t2.b IS NULL); |