我有三张桌子:Guest,JournalEntry& EmailCore包含以下相关列
JournalEntry (je)
------------------------------
id | guestId | emailId | store
EmailCore (ec)
----------
id | store
Guest (g)
----------
id | store
具有以下关系:
je.guestId -> g.id
je.emailId -> ec.id
我刚刚在JournalEntry表上添加了store列,其中包含:
ALTER TABLE `JournalEntry` ADD `store` int(11) NOT NULL;
我正尝试使用以下规则将所有商店数据从EmailCore和Guest迁移到JournalEntry中:
1)如果je.emailId不为null,则使用EmailCore中的商店
2)否则使用来自Guest的商店
我知道,对于JournalEntry中的每一行,在EmailCore或Guest中都有一个商店。
考虑到这一点,我尝试了这个问题:
-- Migrate the proper store number to the store column of JournalEntry
-- If present, EmailCore.store has priority
UPDATE JournalEntry je
LEFT JOIN Guest g on g.id = je.guestId
LEFT JOIN EmailCore ec on ec.id = je.emailId
SET je.store = COALESCE(ec.store, g.store);
这个查询的问题是它试图构建一个从所有三个表(je,ec& g)构建的大表,并且我一直在耗尽内存或者进程在完成之前锁定并且我必须反弹数据库集群。如果我将行限制在0.5密耳左右,我可以使查询工作。但是,JournalEntry包含大约20万条记录。
任何人都可以想到更好/更快的内存密集型方式来完成这项任务吗?也许是一个for循环/程序。欢迎任何建议。
答案 0 :(得分:0)
您的性能问题可能是因为guest
和email_core
中有多个匹配的行。但是,如果重复项不多,那么索引将有助于查询:
create index idx_guest_id_store on guest(id, store);
create index idx_emailcore_id_store on emailcore(id, store);
但是,如果id
已经是主键,那么这几乎一样好。
如果由于连接而获得大量重复行,我首先会建议两个更新:
UPDATE JournalEntry je JOIN
EmailCore ec
on ec.id = je.emailId
SET je.store = ec.store;
UPDATE JournalEntry je JOIN
Guest g
on g.id = je.guestId
SET je.store = g.store;
WHERE je.emailid IS NULL;
然后我会使用子查询简化这些:
UPDATE JournalEntry je
SET je.store = (SELECT ec.store
FROM EmailCore ec
WHERE ec.id = je.emailId
LIMIT 1
);
UPDATE JournalEntry je
SET je.store = (SELECT g.store
FROM Guest g
WHERE g.id = je.guestId
LIMIT 1
)
WHERE je.emailid IS NULL;