这是我的设置:
表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而不是只有一个来执行这种操作(从一个表中选择行中不存在行的行)而不仅仅是一个...
答案 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
注意:
keyA
和keyB
列的类型是否相同,并且不会发生任何转化(在工作实时代码中看到此类...)