Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103725561
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: Mysql/postgreSQL

2008-05-10 23:32:28

    来源: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);

阅读(615) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~