为什么在join on后面有or的条件执行计划只能走nested loop

0


最近发现一个问题,如果在join on后面的条件中加入一段or的条件,执行计划就只能走nested loop,甚至加入Hint都是不允许的。实验情况如下:
1、创建表及构造数据
CREATE TABLE test_20151023(id int);

CREATE TABLE test_20151023_b(id INT, id1 int);

INSERT INTO test_20151023(id)
SELECT 1 id
UNION ALL
SELECT 2 id
UNION ALL
SELECT 3 id
UNION ALL
SELECT 400 id
UNION ALL
SELECT 500 id;

INSERT INTO test_20151023_b(id, id1)
SELECT 1 id, 100 id1
UNION
SELECT 2 id, 200 id1
UNION
SELECT 3 id, 300 id1
UNION
SELECT 4 id, 400 id1
UNION
SELECT 5 id, 500 id1
UNION
SELECT 6 id, 600 id1
UNION
SELECT 7 id, 700 id1
UNION
SELECT 8 id, 800 id1;

这样表test_20151023数据为:
id
1
2
3
400
500


test_20151023_b数据为:
id        id1
1        100
2        200
3        300
4        400
5        500
6        600
7        700
8        800


2、SQL语句如下:
SELECT b.*
FROM test_20151023 a
INNER JOIN test_20151023_b b
ON a.id = b.id
OR
a.id = b.id1


3、执行计划如下:
12.png

从执行计划中可以看出用的是nested loop连接方式
4、在SQL中加入hint,如下:
SELECT b.*
FROM test_20151023 a
INNER HASH JOIN test_20151023_b b
ON a.id = b.id
OR
a.id = b.id1


这里我加入了hash,但是数据库会提示错误,如下:
“消息 8622,级别 16,状态 1,第 1 行
由于此查询中定义了提示,查询处理器未能生成查询计划。请重新提交查询,并且不要在查询中指定任何提示,也不要使用 SET FORCEPLAN。”


5、如果将语句中的OR后面一段注释的话是可以的:
SELECT b.*
FROM test_20151023 a
INNER HASH JOIN test_20151023_b b
ON a.id = b.id
--OR
--a.id = b.id1


想问一下这是什么原理?
是因为当ON后面有OR条件时,执行计划有且只能走nested loop这种方式吗?
如果是的话,原理是什么呢?

还望给予答案,谢谢!
 
已邀请:
0

- 取是能力,舍是境界 2015-10-23 回答

参考下这篇文章吧。
http://blog.csdn.net/starseeke ... 02177

要回复问题请先登录注册