【发布时间】:2017-12-13 17:53:30
【问题描述】:
我的 Oracle 数据库中有三个表:
表 1: 包含 A 公司的员工和电话号码:
EmployeeName, WorkPhone, MobilePhone, PersonalPhone,OtherPhone
Adam,1234,1111,0987,NULL
Catherine,2345,5432,NULL,NULL
Tom, 4567,7654,0101,0002
表 2: 包含 B 公司的员工和电话号码:
EmployeeName, WorkPhone, MobilePhone, PersonalPhone, OtherPhone
David,8888,9999,0000,1245
Sam,4321,5432,NULL,NULL
Clara,4567,7654,0101,NULL
表 3: 包含电话号码,其中电话号码可以记录在第 1 列或第 2 列或两者中:
PhoneNumber1, PhoneNumber2
1234,NULL
7654,7575
0000,1111
1234,4321
NULL,1234
5432,1234
现在,我想将 表 3 中的电话号码与他们各自的员工联系起来,并了解该员工在哪里工作(公司 A 或 B)。挑战在于,Table 2 共有 8 种“匹配”可能性,Table 2 共有 8 种“匹配”可能性(表 A/B 中的每一列都可以连接到任一列 1或 表 3 中的 column2。
数据集很大。 (表 1 中有 20M 行,表 2 中大约有 2M 行)。让我们暂时忽略 Table2,只专注于将 Table1 连接到 Table3。
如果我执行以下操作,查询会非常非常慢(我想它会在某个时候用完临时表空间):
SELECT * FROM Table3 t3
LEFT JOIN Table1 t1
ON (PhoneNumber1 in (WorkPhone, MobilePhone, PersonalPhone, OtherPhone)
OR PhoneNumber2 in (WorkPhone, MobilePhone, PersonalPhone, OtherPhone))
如果我执行以下操作,查询会用完临时表空间(并且我不允许增加该空间)
SELECT * FROM Table3
LEFT JOIN Table1 t1_1
PhoneNumber1 = t1_1.WorkPhone
LEFT JOIN Table1 t1_2
PhoneNumber1 = t1_1.MobilePhone
LEFT JOIN Table1 t1_3
PhoneNumber1 = t1_1.PersonalPhone
...etc
我们如何优化这个查询?
【问题讨论】:
-
您在寻找样本数据的什么输出?您的第一个查询从两个表中获取所有列;第二个从 table1 的多个实例的所有投影中获取所有列,这可能不是您想要的。您实际上需要检索哪些列(来自任一表),如果一个联系人的两个号码匹配,您希望看到什么?
-
查询解释计划向您展示了什么?在寻找优化时从那里开始。