如何在查询提示中为单个表的不同连接选择不同的提示?
Posted
技术标签:
【中文标题】如何在查询提示中为单个表的不同连接选择不同的提示?【英文标题】:How can I choose different hints for different joins for a single table in a query hint? 【发布时间】:2010-03-26 15:08:06 【问题描述】:假设我有以下查询:
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 = B.x 连接发生在 A.z = D.z 之前呢?我意识到在这种情况下我可以先列出 D,但想象 D 随后连接到 E,并且 D-E 连接是我在整个查询中想要的最后一个。
第三种配置——假设我希望 A.x 连接成为整个查询的第一个,并且我希望 A.z 连接成为最后一个。如何使用提示从 A 进行一次连接,然后是 B-C 连接,最后是 A-D 连接?
【问题讨论】:
否 -ORDERED
不采用表名。它告诉优化器在 FROM 子句中使用表的顺序。此外,在 Oracle 10g + 中,LEADING 提示接受任意数量的表 - 例如/*+LEADING(A B C D)*/
【参考方案1】:
首先,使用此类提示应该是最后的手段,而不是编写查询的正常方式。大多数情况下,您应该确保优化器统计数据是最新的,并让 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,那么为什么要有效地关闭它呢?
【讨论】:
我对默认优化的行为非常满意,但是对于这个特定的查询(跨越数据库链接并使用多个视图),当我运行解释时,它显示的估计成本约为 700没有任何提示的计划。当我在没有提示的情况下运行查询时,大约需要 30 秒才能返回。当我指定一个 LEADING 提示时,它会显示 ~950 的成本,但会在 ~3.5 秒内返回。必须达到这种特异性水平非常令人沮丧,但我没有看到任何其他选择。 数据库链接可能会对性能造成很大影响。 DRIVING_SITE 提示在这里很有用 - 请参阅 download.oracle.com/docs/cd/B28359_01/server.111/b28310/…【参考方案2】:在 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 吗?
【讨论】:
我们使用的是 10g。我发现“旧”样式连接比新语法更具可读性。我已经对 ANSI 连接语法进行了几次尝试,但我觉得我并没有获得多少收获。我也有点不确定如何处理在 ON 子句中指定非连接条件,与所有连接都在一个块中时相比,我花了更多的时间从一个地方跳到另一个地方。 作为不久前硬着头皮切换到ANSI join语法的人,一开始我也没有明白这一点。看起来很尴尬。现在我是一个大粉丝。首先,如果您必须使用不同的 DBMS(例如 SQL Server),您将不会遇到语法问题。一旦你改变你的想法,它实际上更直观。你没有人问你“+”号是什么意思。它更具可读性。不知道“一个块中的所有连接”是什么意思,您当然可以在一个选择中拥有多个连接。尽管最初遇到阻力,但我很高兴我做出了改变。以上是关于如何在查询提示中为单个表的不同连接选择不同的提示?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 jquery 函数中为 JQuery UI 工具提示设置不同的 UI 主题