如何在一个表中选择记录而不是另一个具有多个PKID的记录?

时间:2012-10-21 20:48:38

标签: mysql sql join

这是我的设置:

records包含多个(两个以上)PKID列以及其他一些列。

cached_records只有两列,与records的两个PKID相同。

例如,我们假设records有PKID'keyA','keyB'和'keyC',cached_records只有'keyA'和'keyB'。

我需要从records表中提取适当的PKID(因此,'keyA'和'keyB')不在cached_records表中的行。

如果我只使用一个PKID,我知道这个任务有多简单:

SELECT
    pkid
FROM
    records
WHERE
    pkid NOT IN (SELECT pkid FROM cached_records)

但是,有两个PKID的事实意味着我不能使用简单的NOT IN。这就是我目前所拥有的:

SELECT
    `keys`.`keyA` AS `keyA`,
    `keys`.`keyB` AS `keyB`
FROM
    (
        SELECT DISTINCT
            `keyA`,
            `keyB`
        FROM
            `records`
    ) AS `keys`
        LEFT JOIN
                `cached_records` AS `cached`
            ON
                    `keys`.`keyA` = `cached`.`keyA`
                AND
                    `keys`.`keyB` = `cached`.`keyB`
WHERE
    (
            `cached`.`keyA` IS NULL
        AND
            `cached`.`keyB` IS NULL
    )

DISTINCT是必需的,因为我只从records表中抓取多个PKID中的两个,可能有重复,我真的不需要重复;'keyC'不是正在使用它有助于确定记录的唯一性。)

上面的这个查询工作得很好,但是,随着cached_records表的增长,查询需要花费更长的时间来处理(我们现在正在谈论几分钟,有时需要足够长的时间才能使我的代码挂起并崩溃)。

所以,我想知道最有效的方法是使用多个PKIDS而不是只有一个来执行这种操作(从一个表中选择行中不存在行的行)而不仅仅是一个...

1 个答案:

答案 0 :(得分:2)

这应该更快:

SELECT  DISTINCT
    `records`.`keyA` AS `keyA`,
    `records`.`keyB` AS `keyB`
FROM
    `records`
        LEFT JOIN
                `cached_records` AS `cached`
            ON
                    `records`.`keyA` = `cached`.`keyA`
                AND
                    `records`.`keyB` = `cached`.`keyB`
WHERE
            `cached`.`keyA` IS NULL -- one is enough here

注意:

  • 以查询为表,您会失去很多性能。您可以在最外面的SELECT中执行distinct。
  • 如果它们为null,则检查两个密钥中的一个就足够了,因为没有一个可以为null
  • 您应该验证keyAkeyB列的类型是否相同,并且不会发生任何转化(在工作实时代码中看到此类...)
  • 您应该在表格上有适当的索引。这个查询的分钟是可怕的事情的迹象......(或疯狂的数据量)