我的最终目标... SELECT
来自qry1
的所有字段,其中包含家庭电话,手机或工作电话匹配tbl2
这是我当前的SQL语法,它失败了。"失败意味着它在10-15分钟后没有完成执行,而个人在一两分钟内加入每个(独立)运行。
SELECT qry1.*
FROM qry1 INNER JOIN tbl2
ON ((qry1.CellPhone = tbl2.CellPhone)
OR (qry1.HomePhone = tbl2.HomePhone)
OR (qry1.WorkPhone = tbl2.WorkPhone));
问题: 我的SQL语法有错误吗? 有没有更好的方法来完成我的任务? 如果只是单独运行3(Home,work,cell)JOIN查询,UNION它们,然后在必要时进行重复数据删除,对我来说更有意义吗?
答案 0 :(得分:6)
如果个人快速加入工作,则复合OR条件可能很慢,因为它不能使用单个索引,而各个条件可以分别使用单个索引用于三个连接条件。因为它不能使用一个索引,所以它可能正在执行非索引顺序表扫描。 (您应该研究查询计划,以便了解优化程序实际执行的操作。)
鉴于单个查询的工作速度相当快,因此使用UNION会获得更好的性能(除非DBMS中的优化器有盲点):
SELECT qry1.* FROM qry1 INNER JOIN tbl2 ON qry1.CellPhone = tbl2.CellPhone
UNION
SELECT qry1.* FROM qry1 INNER JOIN tbl2 ON qry1.HomePhone = tbl2.HomePhone
UNION
SELECT qry1.* FROM qry1 INNER JOIN tbl2 ON qry1.WorkPhone = tbl2.WorkPhone
这应该会给你一个与3个单独查询一样快的结果。它不会那么快,因为UNION会重复消除(当然,个别查询不会消除)。你可以使用UNION ALL,但是如果两个表中有很多行,其中2或3个字段对匹配,那么可能会导致结果中出现大量重复。
答案 1 :(得分:2)
or
对于SQL优化器来说可能相当困难。我会建议3个索引和以下查询:
SELECT qry1.*
FROM qry1
WHERE EXISTS (SELECT 1 FROM tbl2 WHERE qry1.CellPhone = tbl2.CellPhone) OR
EXISTS (SELECT 1 FROM tbl2 WHERE qry1.HomePhone = tbl2.HomePhone) OR
EXISTS (SELECT 1 FROM tbl2 WHERE qry1.WorkPhone = tbl2.WorkPhone);
三个索引是tbl2(CellPhone)
,tbl2(HomePhone)
和tbl2(WorkPhone)
。
答案 2 :(得分:1)
如果这实际上是一个自我联接,tbl1和qry1中同一个人都存在,那么你可能不会对人们匹配的地方感兴趣,也不会对结果的重复排列感兴趣。我的意思是,自联接通常有两条记录,其中Bob和Jane拥有相同的电话号码,因此您的结果已加入以下记录:
Bob, Jane
Jane, Bob
Jane, Jane
Bob, Bob
其中你可能只需要Bob, Jane
,因为它告诉你那两个人有匹配的电话号码。 如果您有一些唯一的ID,那么添加where qry1.SSN < tbl2.SNN
将消除许多重复项并减少您的结果集。优选地,该列具有索引。
答案 3 :(得分:0)
以下内容与https://stackoverflow.com/a/27696729/4350148类似,但使用不相交的联合。可能更有效率
SELECT qry1.* FROM qry1 INNER JOIN tbl2 ON qry1.CellPhone = tbl2.CellPhone
UNION distinct
SELECT qry1.* FROM qry1 INNER JOIN tbl2 ON
qry1.CellPhone != tbl2.CellPhone
and qry1.HomePhone = tbl2.HomePhone
UNION distinct
SELECT qry1.* FROM qry1 INNER JOIN tbl2 ON
qry1.CellPhone != tbl2.CellPhone
and qry1.HomePhone != tbl2.HomePhone
and qry1.WorkPhone = tbl2.WorkPhone