-1

只是与工作中的一些人讨论编写查询和性能的最佳方式。

限制您的第一个结果集是否更好,以便初始表中的所有连接都有更少的行来连接?

例如:

表:REFCODE 有 ~10,000 行

表:WHSE 有 ~200 行

哪个性能更好?

使用内部连接将行从大型结果集中挤出:

SELECT
  *
FROM
  REFCODE
INNER JOIN
  WHSE ON
  WHSE.RCIDX = REFCODE.RCIDX

首先使用较小的结果集:

SELECT
  *
FROM
  WHSE
INNER JOIN
  REFCODE ON
  REFCODE.RCIDX = WHSE.RCIDX

使用最大的结果集,但使用 where 子句过滤器仅记录我知道将加入第二个表的记录

SELECT
  *
FROM
  REFCODE
INNER JOIN
  WHSE ON
  WHSE.RCIDX = REFCODE.RCIDX
WHERE
  REFCODE.TYPE = 'WHSE'

还是 CBO 会确定类似的解释计划?工作中的人告诉我,您应该始终从尽可能小的结果集开始,但不确定!

任何讨论都值得讨论!

4

1 回答 1

3

对于像您发布的那个简单案例,优化器几乎肯定会为所有三个查询生成相同的查询计划。性能上不会有差异。

通常,查询中表的顺序是无关紧要的。优化器应该根据您在对象上收集的统计信息找出适当的连接顺序和连接方法。有时,当您连接相对大量的表时,优化器将无法考虑所有可能的连接顺序,因为这样做需要超过optimizer_max_permutations环境。发生这种情况时,优化器会使用启发式方法来尝试确定要详细考虑哪些路径以及忽略哪些路径。这些启发式方法并不完美,因此您可能会发现在某些情况下优化器会消除可能导致更好连接顺序的路径。首先列出最严格的表格可能会产生对计划的偏见,因为这可能是最有效的驱动表格。但这在很大程度上是一个极端情况。

Jonathan Lewis 有一篇关于子句中表的顺序如何FROM影响查询计划的好文章。但是对于您可能编写或遇到的绝大多数查询,表的顺序是无关紧要的。

回到旧的基于规则的优化器时代,当时 Oracle 7.3.4 是闪亮的和新的,恐龙在地球上漫游,基于规则的优化器将使用表的顺序来生成计划。我敢打赌,你正在与之交谈的人要么已经足够大,在那些日子里已经存在,要么正在传递他们从那些老开发人员那里学到的规则。

即使不再(在几乎所有情况下)任何性能优势,构建查询的一致方法也可能是有益的。例如,如果您始终将前导表放在首位,这可能会鼓励开发人员考虑预期的查询计划并更加深思熟虑地编写代码。如果优化器在生成查询计划时是否按照您的预期执行,它可以让您更容易相对快速地查看,以便提示您了解有关对象的统计信息的问题。

于 2013-07-19T03:45:48.927 回答