1

这是我的设置:

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

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

例如,假设recordsPKID 为“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 而不是一个...

4

1 回答 1

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 中执行不同的操作。
  • 检查两个键之一是否为空就足够了,因为没有一个可以为空
  • 您应该验证keyAkeyB列是否属于同一类型,并且不会发生转换(在工作实时代码中可以看到......)
  • 您应该在表上有适当的索引。此查询的分钟数表明正在发生可怕的事情......(或疯狂的数据量)
于 2012-10-21T21:23:39.493 回答