使用3个密钥

时间:2017-01-06 20:46:44

标签: sql oracle

假设我有表A和表B.两个表都包含大约500,000条记录。 Cat,Dog和Mouse为两个表提供了完全相同的数据类型,但是一个表中的数据可能不在另一个表中。

表动物园:

Cat | Dog | Mouse | Bird
xyz   dfg    sdhf   123
dfr   kjf    asdc   456
zxc   abc    qwrt   789

表Pet_Store:

Cat | Dog | Mouse | Pig
ghf   dsa    dfre   12
dfr   gfr    qwy5   19
zxc   abc    dfgr   21

期望的结果:

  Cat | Dog | Mouse
  dfr   kjf   asdc
  zxc   abc   qwrt

我想查询Cat,Dog或Mouse相同的每条记录。这里没有用于连接两个表的唯一键,我们可以用这三个字段绘制连接的唯一方法。如果存在至少一个匹配,则返回Cat,Dog和Mouse。我自己做了一个选择声明,但考虑到我正在使用的数据是非常大的,这个过程需要很长时间,所以我认为我没有效率。有什么建议吗?:

select n.Cat, n.Dog, n.Mouse
from Zoo n, Pet_Store t
where
(n.Cat =t.Cat or n.Dog =t.Dog or n.Mouse =t.Mouse)

编辑:对不起,我应该包括更多的清晰度。我的大脑此刻正在炒,所以我为此道歉。如果我检查匹配的任何字段,请从Zoo表中提取Cat,Dog,Mouse字段。

3 个答案:

答案 0 :(得分:1)

根据您对重复项的关注程度,您可以执行类似

的操作
select z.cat, z.dog, z.mouse from zoo z inner join pet_store p on z.cat   = p.cat
union all
select z.cat, z.dog, z.mouse from zoo z inner join pet_store p on z.dog   = p.dog
union all
select z.cat, z.dog, z.mouse from zoo z inner join pet_store p on z.mouse = p.mouse

这将允许所有列的索引使用(假设您在两个表上都有适当的索引)。

答案 1 :(得分:-1)

嗯,你没有告诉我们多少,但鉴于你告诉我们的事情,我会这样做。

SELECT A.Cat, A.Dog, A.Mouse
FROM Zoo A
LEFT JOIN Pet_Store B1 ON A.Cat = B1.Cat
LEFT JOIN Pet_Store B2 ON A.Dog = B2.Dog
LEFT JOIN Pet_Store B3 ON A.Mouse = B3.Mouse
WHERE COALESCE(B1.Cat, B2.Dog, B3.Mouse) IS NOT NULL

由于我们对数据的结构或有关列或表的其他信息一无所知,因此我知道无法改进此查询。但是,如果您确实有任何索引 - 此查询将以最佳方式使用它们。

例如,可以在此查询中使用B.Mouse上的索引,但不在示例查询中使用。

答案 2 :(得分:-1)

您的查询没有什么问题,您在一张相当大的表上没有处理索引和表扫描。通过稍微重构查询,您会看到略有改进,但通过添加索引,您会看到更显着的性能改进。

SELECT z.Cat, z.Dog, z.Mouse
FROM Zoo z
  INNER JOIN Pet_Store p ON
    z.Cat = p.Cat OR
    z.Dog = p.Dog OR
    z.Mouse = p.Mouse

这将返回您正在寻找的数据 - 无需多次加入表格。