Oracle SQL:联合和联接
我有一个表ACCPLAN(主键:ACCOUNT\u ID) 我还有一个表ACCTRANSACTION(主键->(帐户ID,事务ID) 有5种固定计划类型和20种固定txn类型。只有少数交易类型是固定的 每个计划类型都可能。(例如:TXN类型1和TXN类型2可能用于 计划类型1和TXN类型2以及TXN类型3可用于计划类型2) 我正在尝试从ACCTRANSACTION和其他中检索交易信息Oracle SQL:联合和联接,sql,oracle,join,Sql,Oracle,Join,我有一个表ACCPLAN(主键:ACCOUNT\u ID) 我还有一个表ACCTRANSACTION(主键->(帐户ID,事务ID) 有5种固定计划类型和20种固定txn类型。只有少数交易类型是固定的 每个计划类型都可能。(例如:TXN类型1和TXN类型2可能用于 计划类型1和TXN类型2以及TXN类型3可用于计划类型2) 我正在尝试从ACCTRANSACTION和其他中检索交易信息 ACCP计划中的详细信息 这可以通过两种方式实现 方法1 检索每个计划类型并执行联合 select ap.acc
ACCP计划中的详细信息 这可以通过两种方式实现 方法1 检索每个计划类型并执行联合
select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id = at.account_id
and ap.plan_type = PLAN_TYPE_ONE
and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2);
union
select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id = at.account_id
and ap.plan_type = PLAN_TYPE_TWO
and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3);
union
...
方法2
使用一个查询检索所有计划类型
select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id = at.account_id
and
((ap.plan_type = PLAN_TYPE_ONE and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2))
or
(ap.plan_type = PLAN_TYPE_TWO and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3));
考虑到两个表都有大量数据,哪种方法更好?请建议。使用联接。联接需要对整个结果进行排序,这对数据库来说是一项昂贵的操作 此外,最好只读取一次表并对每条记录进行一些复杂的检查,而不是只为了进行较小的检查而多次读取
免责声明:我可以想象一些非常奇怪的情况,第一个查询运行得更快,如果数据库查询规划者认为大的条件没有足够的选择性,没有使用索引,而每个较小的条件都使用索引。行数越大,我就越会使用第二个选项。我投票关闭,因为你uestion是基于意见的,因此这是离题的。您应该对这两个查询运行解释说明,看看哪一个查询最适合您的数据库。我理解在这种情况下,“最佳”只意味着最快。在已知数据库(Oracle)中,这一点可以测量和复制。即使很多事情可能会影响结果(索引、统计信息、版本、配置选项、硬件)了解数据库的执行计划可以让您很好地了解什么可以更快。无论如何,定期会有许多与性能相关的问题可以重定向到某个stackexchange站点。Meta中是否有与此相关的内容?与您的问题无关:您应该停止使用过时的IMPLIT它在
where
子句中联接,并使用显式JOIN
运算符(在from
子句中)。我也同意第二个可能更有效。如果您确实想要第一个,您应该使用UNION ALL
,以避免删除重复项的开销。+1很好的解释和免责声明。值得注意的是,Oracle确实有一些与UNION
相关的不同转换,但没有其中一个应用于此处。例如,提示将或
转换为联合所有
,并可以防止在联合所有
中重新读取大型表。奇怪的是,联合分解只适用于更复杂的场景,对这些简单的查询没有帮助。使用联合所有
时可以避免排序而不是UNION
UNION-ALL更快。如果他不介意重复,或者如果他确信没有重复,他可以使用它们。即使使用UNION-ALL,我也会打赌使用显式连接运算符进行连接,正如你所说的。
select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id = at.account_id
and ap.plan_type = PLAN_TYPE_ONE
and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2);
union
select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id = at.account_id
and ap.plan_type = PLAN_TYPE_TWO
and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3);
union
...
select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id = at.account_id
and
((ap.plan_type = PLAN_TYPE_ONE and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2))
or
(ap.plan_type = PLAN_TYPE_TWO and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3));