Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在查询提示中为单个表的不同联接选择不同提示?_Sql_Oracle_Optimizer Hints_Query Hints - Fatal编程技术网

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

Sql 如何在查询提示中为单个表的不同联接选择不同提示?,sql,oracle,optimizer-hints,query-hints,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上使用索引提示,但在a.z上使用哈希提示?提示似乎只采用表名,而不采用特定的联接,因此当使用具有多个联接的单个表时,我只能为所有联接指定一个策略 或者,假设我在上述查询中使用前导或有序提示。这两个提示也只使用一个表名,因此如何确保a

假设我有以下查询:

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上使用索引提示,但在a.z上使用哈希提示?提示似乎只采用表名,而不采用特定的联接,因此当使用具有多个联接的单个表时,我只能为所有联接指定一个策略

或者,假设我在上述查询中使用前导或有序提示。这两个提示也只使用一个表名,因此如何确保a.x=B.x连接在a.z=D.z连接之前发生?我意识到在这种情况下我可以先列出D,但是想象D随后连接到E,并且D-E连接是我在整个查询中想要的最后一个连接


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

在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中的语法是什么样子的,顺便问一下,为什么要使用旧式连接?您仍然使用8i吗?

首先,使用这些提示应该是最后的手段,而不是编写查询的正常方式。大多数时候,你应该确保Optimizer统计数据是最新的,让CBO为自己制定最佳路径——这是它的工作

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

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) */ *

但重申一下,很少需要这样做。Oracle已经在开发CBO上投入了数百万美元和人力,那么为什么要有效地关闭它呢?

我对默认优化的行为非常满意,但是对于这个特定的查询,它跨越了一个DB链接并使用了多个视图,当我在没有任何提示的情况下运行解释计划时,它显示了大约700美元的成本。当我在没有提示的情况下运行查询时,需要大约30秒才能返回。当我指定前导提示时,它显示约950的开销,但在约3.5秒后返回。必须达到这样的特殊性水平是非常令人沮丧的,但我看不到任何其他选项。DB链接可能会对性能造成很大影响。这里的DRIVING_站点提示很有用-请看我们使用的是10g。我发现旧式连接比新语法更具可读性。我已经尝试了几次ANSI join语法,但是我觉得我没有得到多少。我也有点不确定在ON子句中指定非连接条件是如何处理的,我花了很多时间从一个地方跳到另一个地方,而不是所有连接都在一个块中。作为一个在不远的过去咬紧牙关并切换到ANSI连接语法的人,起初我也不明白这一点。看起来很尴尬。现在我是一个超级粉丝。首先,如果您必须使用不同的DBMS,例如SQL Server,您将不会在语法方面遇到困难。一旦你改变你的想法,它实际上更直观。你不会有人问你+符号是什么意思。更具可读性。我不知道一个块中的所有联接是什么意思,您当然可以在一个select中有多个联接。我很高兴我做出了改变,尽管最初遇到了阻力。它告诉优化程序使用FROM子句中表格的顺序。此外,在Oracle 10g+中,前导提示接受任意数量的表,例如/*+前导A B C D*/