与工作中的一些人讨论编写查询和性能的最佳方法。
限制你的第一个结果集是否更好,以便初始表中的所有连接都有更少的行加入?
例如:
表: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会否确定类似的解释计划? 这里的工作人员告诉我,你应该总是从最小的结果集开始,但不确定!
任何讨论都是适用的!
答案 0 :(得分:3)
对于像您发布的那样的简单情况,优化器几乎肯定会为所有三个查询生成相同的查询计划。性能没有差异。
通常,查询中表的顺序无关紧要。优化器应根据您在对象上收集的统计信息确定适当的连接顺序和连接方法。有时,当您加入相对大量的表时,优化器将无法考虑每个可能的连接顺序,因为这样做需要超过optimizer_max_permutations
设置。当发生这种情况时,优化器使用启发式方法来尝试确定要详细考虑哪些路径以及要忽略哪些路径。这些启发式方法不完善,因此您可能会发现优化程序会消除导致更好的连接顺序的路径。首先列出限制性最强的表可能会产生对计划的偏见,因为这可能是最有效的驱动表。但这是一个极端的案例。
Jonathan Lewis有一篇关于如何the order of tables in the FROM
clause can affect the query plan的好文章。但对于您可能会编写或遇到的绝大多数查询,表的顺序无关紧要。
回到旧的基于规则的优化器时代,当Oracle 7.3.4闪亮,新的恐龙在地球上漫游时,基于规则的优化器将使用表的顺序来生成计划。我打赌,那些与你交谈的人要么已经足够大,要么已经在那些日子里存在,要么正在传递他们被那些老开发者教授的规则。
即使不再(几乎在所有情况下)任何性能优势,构建查询的一致方法也是有益的。例如,如果您始终将前导表放在首位,那么可能会鼓励开发人员考虑预期的查询计划并更仔细地编写代码。如果优化器在生成查询计划时正在执行您期望的操作,那么它可以更容易地相对快速地查看,以便了解您对对象的统计信息的问题。