如何在查询提示中为单个表的不同联接选择不同的提示?
假设我有以下查询:
select * from A, B, C, D
where A.x = B.x
and B.y = C.y
and A.z = D.z
我在 Ax、Bx、By、Cy 和 Dz 上有索引
Az 上没有索引
我如何向此查询提供提示,以在 Ax 上使用 INDEX 提示,但在 Az 上使用 USE_HASH 提示?提示似乎只采用表名,而不是特定的联接,因此当使用具有多个联接的单个表时,我只能为所有联接指定一个策略。
或者,假设我在上述查询中使用 LEADING 或 ORDERED 提示。这两个提示也只接受表名,那么如何确保 Ax = Bx 连接发生在 Az = Dz 连接之前?我意识到在这种情况下我可以先列出 D,但想象 D 随后连接到 E,并且 DE 连接是我在整个查询中想要的最后一个连接。
第三种配置——假设我希望 Ax 连接成为整个查询的第一个连接,而我希望 Az 连接成为最后一个连接。如何使用提示从 A 进行单个连接,然后是 BC 连接,最后是 AD 连接?
Suppose I have the following query:
select * from A, B, C, D
where A.x = B.x
and B.y = C.y
and A.z = D.z
I have indexes on A.x and B.x and B.y and C.y and D.z
There is no index on A.z.
How can I give a hint to this query to use an INDEX hint on A.x but a USE_HASH hint on A.z? It seems like hints only take the table name, not the specific join, so when using a single table with multiple joins I can only specify a single strategy for all of them.
Alternative, suppose I'm using a LEADING or ORDERED hint on the above query. Both of these hints only take a table name as well, so how can I ensure that the A.x = B.x join takes place before the A.z = D.z one? I realize in this case I could list D first, but imagine D subsequently joins to E and that the D-E join is the last one I want in the entire query.
A third configuration -- Suppose I want the A.x join to be the first of the entire query, and I want the A.z join to be the last one. How can I use a hint to have a single join from A to take place, followed by the B-C join, and the A-D join last?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,使用此类提示应该是最后的手段,而不是编写查询的正常方式。大多数时候,您应该确保优化器统计数据是最新的,并让 CBO 为自己找出最佳路径 - 这就是它的工作!
INDEX 提示可以指定要使用的索引的名称,如下所示:(
假设 AX 上的索引称为 A_X_IDX)。
您不能告诉 Oracle 在同一语句中使用 AX 上的索引和使用与表 A 的哈希连接,这是没有意义的。但是,您可以(如果必须)为每个表指定访问路径,如下所示:
但重申一下,需要这样做的情况应该是罕见。 Oracle 已投入数百万美元和人力来开发 CBO,那么为什么要有效地关闭它呢?
First of all, using such hints should be the last resort, not a normal way of writing queries. Most of the time you should just ensure that optimiser stats are up to date and let the CBO work out the optimum path for itself - that's its job!
The INDEX hint can specify the name of the index you want to use like this:
(assuming the index on A.X is called A_X_IDX).
You can't tell Oracle use use the index on A.X and use a hash join to table A in the same statement, that makes no sense. However, you can (if you must) specify the access path for each table something like:
But to reiterate, it should be rare to need to do this. Oracle have invested millions of dollars and manhours into developing the CBO, so why effectively switch it off?
在 SQL Server 上,您可以像这样执行哈希联合提示
,还可以提供索引提示
不知道 Oracle 中的语法是什么样的,顺便说一句,为什么您使用旧式联合?你还在用8i吗?
On SQL Server, you would do a hash joint hint like this
and you can also supply an index hint
Don't know what the syntax looks like in Oracle, BTW why are you using old style joins? Are you still on 8i?