如何在查询提示中为单个表选择不同联接的不同提示?

时间:2010-03-26 15:08:06

标签: sql oracle optimizer-hints query-hints

假设我有以下查询:

select * from A, B, C, D
where A.x = B.x
and B.y = C.y
and A.z = D.z

我有A.x和B.x以及B.y和C.y以及D.z

的索引

A.z。

上没有索引

如何提示此查询以在A.x上使用INDEX提示但在A.z上使用USE_HASH提示?似乎提示仅采用表名而不是特定连接,因此当使用具有多个连接的单个表时,我只能为所有连接指定单个策略。

替代方案,假设我在上述查询中使用了LEADING或ORDERED提示。这两个提示也只是一个表名,所以如何确保A.x = D.z连接发生在A.z = D.z之前?我意识到在这种情况下我可以先列出D,但想象D随后加入E并且D-E连接是我在整个查询中想要的最后一个。

第三种配置 - 假设我希望A.x连接成为整个查询的第一个,我希望A.z连接​​成为最后一个。如何使用提示从A进行单个连接,然后进行B-C连接,最后进行A-D连接?

2 个答案:

答案 0 :(得分:3)

首先,使用此类提示应该是最后的手段,而不是编写查询的常规方法。大多数情况下,您应该确保优化统计数据是最新的,让CBO为自己制定最佳路径 - 这就是它的工作!

INDEX提示可以指定您要使用的索引的名称,如下所示:

SELECT /*+ INDEX (A, A_X_IDX) */ *
...

(假设A.X上的索引称为A_X_IDX)。

你无法告诉Oracle使用A.X 上的索引和在同一语句中对表A使用散列连接,这没有任何意义。但是,您可以(如果必须)为每个表指定访问路径,如:

SELECT /*+ INDEX (A, A_X_IDX) INDEX(B, B_Y_IDX) USE_HASH(C) */ *

但重申一下,应该罕见需要这样做。甲骨文已投入数百万美元和人力资源开发CBO,为什么要有效地关闭它呢?

答案 1 :(得分:0)

在SQL Server上,您可以像这样执行哈希联合提示

SELECT * FROM table1 t1
INNER hash join table2 t2 ON  t1.id = t2.id

您还可以提供索引提示

select * from table1 t1
inner  join table2 t2 with (index( bla))  on  t1.id = t2.id

不知道Oracle中的语法是什么样的,BTW为什么要使用旧式连接?你还在8i吗?