这是我的设置:如何选择一个表中的记录,但不是多个PKID的记录?
表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)
然而,事实上,在两个PKIDs意味着我不能用一个简单的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
表抓住两个多PKIDs的,有可能是重复的,我真的不需要重复;“keyC '没有被使用,它有助于确定记录的唯一性)。上面的查询工作得很好,但是,随着cached_records
表增长,查询需要更长和更长的时间来处理(我们现在正在谈论分钟,有时需要足够长的时间才能让代码挂起并崩溃)。
所以,我想知道什么是最有效的方式来做这种操作(从一个表中选择行不存在于另一个表中的行)与多个PKIDS而不是只有一个...
我实施了一些建议,但这是杀手:他们的钥匙是不同的类型! (我认为我已经修复了这个问题,但是在倾倒和恢复不同的数据库转储时,我想我最终使用了一个没有固定的转储...),所以我加入了一个pkids作为整数的表,其他作为varchars。 – jzimmerman2011
为什么是杀手?无法例如'records.keyA = CAST(cached.keyA AS INTEGER)'解决这个问题? –
@TerjeD它甚至不需要,MySQL为你做。问题不在于**不能正常工作**,而是因为它非常麻烦。 – ppeterka