2011-09-07 70 views
1

作为继承系统的一个非常缓慢的重构过程的一部分,我需要消除一些慢连接和子查询。当我熟悉这个系统的时候,我正在慢慢地清理数据库结构,摆脱磁带上的感觉,进行渐进式改进,希望在此期间没有任何突破。其中一部分涉及将来自两个由三分之一链接的表格的数据合并为一个。通过链接表将某个表的列中的某些数据复制到另一个列中

表结构与此类似:

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的值,这些值实际上不是项目的属性,而是项目所属的组的属性。 (这会导致问题,因为如果项目位于另一个组中,则值可能会有所不同)。

我无法从项目表中删除字段,因为它们是由几乎疯狂的数据源中的疯狂导入过程填充的。在我修复导入过程之前,我一直坚持让项目表中存在字段,但在短期内,至少我可以消除缓慢查找来获取它们。

现在我在PHP中有一个遍历每个组的循环,从它遇到的第一个项目中获取值(这很好 - 组中的所有项目将具有a,b和c的相同值)并将它们放入组中。这个过程非常缓慢且费力,而且不幸的是在超负荷和动力不足的服务器上运行频繁。有没有一种巧妙的方法可以将项目表中的这些(只有这些)值复制到组表中,并让MySQL完成繁重的工作,而不是依赖PHP脚本?

回答

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; 

似乎做什么,我需要。

相关问题