作为继承系统的非常慢的重构过程的一部分,我需要消除一些慢连接和子查询。当我熟悉系统时,我正在慢慢消毒数据库结构,摆脱管道缠绕的感觉,进行渐进式改进,希望在此期间不会出现任何问题。部分原因是将来自两个表的数据组合成一个三分之一。
表结构类似于:
CREATE TABLE groups
(
group_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
-- various other fields that are appropriate to groups
...
-- these fields need to be filled
a ENUM(...) NOT NULL,
b INTEGER NOT NULL,
c VARCHAR(...) NOT NULL
);
CREATE TABLE items
(
-- key is determined by an external data source
item_id INTEGER NOT NULL PRIMARY KEY,
-- various other fields that are appropriate to items
...
-- these fields shouldn't be here, but in the groups table
a ENUM(...) NOT NULL,
b INTEGER NOT NULL,
c VARCHAR(...) NOT NULL
);
CREATE TABLE group_items
(
item_id INTEGER NOT NULL,
group_id INTEGER NOT NULL,
PRIMARY KEY (item_id,group_id)
);
项目可能位于多个组中。表“items”中的每个记录具有列a,b和c的值,这些列实际上不是项目的属性,而是项目是其一部分的组。 (这会导致问题,因为如果项目在另一个组中,则值可能不同。)
我无法从items表中删除字段,因为它们是由几乎疯狂的数据源中的疯狂导入过程填充的。直到我开始修复导入过程,我仍然坚持在items表中存在字段,但在短期内至少我可以消除慢速查找以获取它们。
现在我有一个PHP循环遍历每个组,从它遇到的第一个项目获取值(这很好 - 组中的所有项目将具有相同的a,b和c值)和将它们放入组中。这个过程相当缓慢和费力,不幸的是,在一个过载和功能不足的服务器上运行非常频繁。有没有一种聪明的方法可以将这些(并且只有这些)值从items表复制到groups表中,让MySQL做得很重,而不是依赖于PHP脚本?
答案 0 :(得分:0)
看起来我找到了自己的答案。由于每个组中的项目数量相对较少,可能会有一些重复的工作,但它不是瓶颈,而且比PHP循环快得多:
UPDATE
groups g
INNER JOIN group_items USING(group_id)
INNER JOIN items i USING(item_id)
SET
g.a = i.a,
g.b = i.b,
g.c = i.c;
似乎做我需要的。