sql - 多个一对多连接同一张表的性能

标签 sql oracle join database-performance

假设我有一个表Client,它被多个表引用,例如ProfileAddressPhoneAccount...通过所有这些表中的 client_id 列。

因此,一个客户可能有多个个人资料、多个地址等等。

我需要通过单个查询获取所有Client的信息。

如果我写这样的查询

SELECT C.*, PR.*, AD.*, PH.*, AC.* FROM CLIENT C 
    LEFT OUTER JOIN PROFILE PF ON C.ID=PF.CLIENT_ID
    LEFT OUTER JOIN ADDRESS AD ON C.ID=AD.CLIENT_ID
    LEFT OUTER JOIN PHONE PH ON C.ID=PH.CLIENT_ID
    LEFT OUTER JOIN ACCOUNT AC ON C.ID=AC.CLIENT_ID

并且帐户有 10 个个人资料、10 个地址、10 个电话和 10 个帐户,结果集中我最终会得到 10000 (10x10x10x10) 行,尽管我只需要 40 (10+10+10+10)。

我应该更好地编写多个查询还是有简单的方法可以使数据库产生更少的行?

更新:添加示例数据:

客户端

ID     | Name       | ...
------ | -----------|-----
1      | "John Doe" |

简介

ID     | CLIENT_ID | TYPE        | ...
------ | --------- | ----------- | ---
1      | 1         | "Primary"   |
2      | 1         | "Secondary" |
3      | 1         | "Work"      |
4      | 1         | "Office"    |
5      | 1         | "Vacation"  |
...

“地址”

ID     | CLIENT_ID | ADDRESS_TEXT | ...
------ | --------- | ------------ | ---
1      | 1         | "Paris, ..." |
2      | 1         | "London..."  |
3      | 1         | "Tokyo..."   |
4      | 1         | "Moscow"     |
5      | 1         | "New York"   |
...

“帐户”

ID     | CLIENT_ID | ACCOUNT_NUM  | ...
------ | --------- | ------------ | ---
1      | 1         | "0012301230" |
2      | 1         | "0172456123" |
3      | 1         | "1234001234" |
4      | 1         | "6789134834" |
5      | 1         | "2378166341" |
...

我不知道 ResultSet 中会出现哪个响应。通常这只是连接,一切都很好 - 这是我第一次开始考虑性能。

最佳答案

据我了解,主要问题是结果集中的数据重复。因为您不需要为任何地址重复任何电话号码。我认为这个决定可能是对每一行进行排名并按排名加入

with CLIENT(ID) as (
select 1 from dual)
,PROFILE (CLIENT_ID, PROFILE) as (
    select 1, 'p1' from dual union all
    select 1, 'p2' from dual union all
    select 1, 'p4' from dual
)
,ADDRESS (CLIENT_ID, ADDRESS) as (
    select 1, 'H1' from dual union all
    select 1, 'H2' from dual
)
,PHONE (CLIENT_ID, PHONE) as (
    select 1, '+13123411' from dual union all
    select 1, '+1234512344' from dual  union all
    select 1, '+12345123133' from dual  union all
    select 1, '+12345123123' from dual  union all
    select 1, '+1234512144' from dual  union all
    select 1, '+12345123123' from dual  union all
    select 1, '+1234512144' from dual  union all
    select 1, '+12345123123' from dual  union all
    select 1, '+1234512144' from dual  union all
    select 1, '+12345123123' from dual  union all
    select 1, '+1234512144' from dual
)
,ACCOUNT (CLIENT_ID, ACCOUNT) as (
    select 1, 'Acc1' from dual union all
    select 1, 'acc2' from dual
)
SELECT PROFILE ,ADDRESS ,PHONE ,ACCOUNT 
from 
(select rownum as RN, PROFILE from PROFILE PR where  PR.CLIENT_ID IN (select id from CLIENT c where c.id = 1))  a 
full outer join (select rownum as RN, ADDRESS from ADDRESS PR where  PR.CLIENT_ID IN (select id from CLIENT c where c.id = 1))  b  on a.rn = b.rn
full outer join (select rownum as RN, PHONE from PHONE PR where  PR.CLIENT_ID IN (select id from CLIENT c where c.id = 1))  c  on a.rn = c.rn
full outer join (select rownum as RN, ACCOUNT from ACCOUNT PR where  PR.CLIENT_ID IN (select id from CLIENT c where c.id = 1)) d  on a.rn = d.rn

关于sql - 多个一对多连接同一张表的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42692605/

相关文章:

sql - 如何在 SQL (Oracle) 中随机排列数据?

mysql - 为什么这个左外连接会产生错误的结果?

mysql - 连接三个 MySQL 表并从一个表中获取最大值

mysql - 解释 SQL 连接语句

sql - 将序列号转换为日期

java - 使用 hibernate 注解映射 @ManyToMany 关系

oracle - 相当于 postgres 中 Oracle 的 pragma autonomous_transaction

oracle - ORA-29534 : referenced object cannot be resolved (Loadjava) error

c# windows窗体在多线程时不响应

sql - 1 个工作日回到 SQL DB2