我注意到在多个表上实现目标的方法有两种。结果集中的列将被更新,速度可能是一个要求。结果集是通过以下方法获得的:
案例1:
select ert.*
from eval_rep_track ert
inner join
(
select erp.evaluation_fk, erp.report_type, LTRIM(erp.assign_group_id, '/site/') course_name
from eval_report_dup@prod erp
inner join eval_report er
on er.id = erp.id
where erp.status='queue'
and er.status='done'
) cat
on ert.eval_id || '.' || ert.report_type || '.' || ert.course_name = cat.evaluation_fk || '.' || cat.report_type || '.' || cat.course_name;或
案例2:
select ert.*
from eval_rep_track ert
inner join
(
select erp.evaluation_fk, erp.report_type, LTRIM(erp.assign_group_id, '/site/') course_name
from eval_report_dup@prod erp
inner join eval_report er
on er.id = erp.id
where erp.status='queue'
and er.status='done'
) cat
on ert.eval_id = cat.evaluation_fk
and ert.report_type = cat.report_type
and ert.course_name = cat.course_name;两者都给出了相同的结果,只有连接条件发生了变化。哪个会跑得更快?
eval_id是NUMBER,report_type和course_name是VARCHAR2。
从使用的开发人员中,案例1具有以下统计信息: SELECT - 3077行、0.048秒结果集获取.执行1语句、3077行受影响、exec/获取时间: 0.048/0.236秒1成功、0警告、0错误
当案例2: SELECT - 3077行(S),0.019秒的结果集被获取.执行1语句,3077行受影响,exec/获取时间: 0.019/0.194秒1成功,0警告,0错误
结果表明,案例2更快。这在任何平台(ide、developer)和数据库中都是通用的吗?这取决于数据类型还是连接总是很昂贵的?我其实不需要连接的结果。谢谢。
发布于 2015-04-29 19:46:04
我认为连在一起的版本通常都会慢一些。
如果您单独比较的任何列都有索引,数据库通常能够使用这些索引来优化连接。当您比较连接时,它必须执行完整的表扫描,因为计算的结果不会在索引中。
即使没有对列进行索引,数据库仍然可以更有效地执行比较。它一次比较一对列,并在其中一个比较失败时立即停止。当使用级联时,它必须首先组合所有列,在两行中,然后进行字符串比较。
最后,如果任何列都是数字的,则连接将需要将数字转换为字符串的附加步骤。
发布于 2015-04-29 20:08:45
很简单,在各个列上连接是正确的。连接到连接值是不正确的。与任何关于性能的讨论不同,您应该编写正确的代码。
对于任何特定的查询,您可能都可以使用连接来编写一个大部分正确的查询。但是,您几乎肯定会引入一些微妙的But,当您获得您不希望得到的数据时,这些But会咬您一口。在这种情况下,一旦列包含句点,就有可能不正确地匹配数据('a.b' || '.' || null = 'a' || '.' || 'b.')。在其他情况下,您可能会遇到其他微妙的问题--日期和数字可能会使用不同的会话级别设置隐式转换为字符串,这些设置可能会产生不同的结果(您的NLS_DATE_FORMAT可能包含时间组件,也可能不包含时间的比较)。如果您经常连接列,那么您将得到许多查询,这些查询基于表中的数据和执行代码的用户都有非常微妙的bug。从维护和支持的角度来看,这是很糟糕的。绩效最多应该是次要的问题。
从性能的角度来看,正确的连接几乎肯定会优于级联方法。当您正确地加入时,优化器将能够在生成查询计划时考虑连接中的各个列的正常索引。如果您正在连接值,那么Oracle最多可以对普通索引进行全面扫描,以获得需要连接在一起的所有数据。但是这样做的效率可能要低得多(特别是当您有超过几千行时)。
从理论上讲,对于某些查询,级联方法会更有效吗?好的。施虐狂开发人员可能会在连接结果上创建基于函数的索引,避免在单个列上创建索引,并在连接方法更有效的情况下生成测试用例。但是,通过在基本列上创建相应的索引(或索引),可以很容易地纠正这一点。对于某些查询,连接是否可能更有效,因为它阻止优化器使用它想要使用的索引?好的。但是,这几乎可以肯定地表明,您在优化器设置或统计数据方面存在问题,应该解决这些问题,而不是在问题上抛出一个创可贴。
发布于 2015-04-29 19:44:46
这取决于表上的索引。通常,索引是用列列表定义的,而不是通过列的连接(作为表达式)来定义的,因此作为经验规则,第二个版本的索引速度要比通常的快。
也就是说,dba可能(无论出于什么原因,可能是醉酒还是精神错乱)决定为列的连接创建一个索引。在这种情况下,语句的第一个版本可以使用索引,而第二个版本可以不使用索引。
https://stackoverflow.com/questions/29953019
复制相似问题