2013-06-29 68 views
0

我正在使用UPDATE通过将m2与n1匹配,在n2中找到相应的值并将其插入到m3中来填充缺少的值(以m3为单位)。表mmm有250万行,而表nnn有55,000行。使用MySQL在大型表上运行更新非常慢

以下两个查询都可以工作,但问题在于性能。现在,我正以零碎的方式更新嗯。我已经将nnn减少到第一行10,000行。在这种情况下,这个部分查询完成了我想在7小时后完成的约18%。这种方法的问题是我必须以这种方式进行10次左右的查找。我知道这是很多计算,但我认为有更好的方法。

有什么办法可以加快这个过程吗?我很欣赏这些反馈。

查询#1

UPDATE mmm, nnn 
SET mmm.m3 = nnn.n2 
WHERE mmm.m2 = nnn.n1 

查询#2

UPDATE mmm a 
    INNER JOIN nnn b 
     ON b.n1 = a.m2 
SET a.m3 = b.n2 
WHERE b.n1 = a.m2 

表MMM(仅组合是唯一的)

m1   m2    m3 
0002-1962  0025117388 
0002-1962  14644418453  
0003-2417  0026708363 

表NNN(n1是唯一的)

n1   n2 
0025117388 1111-2222 
14644418453 1515-2323 
0026708363 1515-2323 

数据库结构:

CREATE TABLE `mmm` (
    `m1` char(9) NOT NULL DEFAULT '', 
    `m2` varchar(11) NOT NULL DEFAULT '', 
    `m3` char(9) NULL DEFAULT '' 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

CREATE TABLE `nnn` (
    `n1` varchar(11) NOT NULL DEFAULT '', 
    `n2` char(9) NOT NULL DEFAULT '' 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 
+0

查询#1 /#2执行后通常会更新多少条记录? –

回答

4

您可以使用EXPLAIN在查询前看到MySQL将如何处理执行。如果没有任何索引,必须对250万行进行全表扫描以从mmm中选择。首先指定主键,以便mysql可以将它们用作查询的索引。您可能会发现您还需要在m2列中添加非唯一索引来加速该选择。

CREATE TABLE `mmm` (
    `m1` varchar(9) NOT NULL DEFAULT '', 
    `m2` varchar(11) NOT NULL DEFAULT '', 
    `m3` varchar(9) NULL DEFAULT '', 
    primary key (m1, m2, m3) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

CREATE TABLE `nnn` (
    `n1` varchar(11) NOT NULL DEFAULT '', 
    `n2` varchar(9) NOT NULL DEFAULT '', 
    primary key (n1) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 
+0

我做了你所说的一切,它运作得非常棒。 (创建主键有帮助,但重要的变化是以m2为单位创建索引。)我能够在不到20秒的时间内以nmn的全部50k条记录更新250万条记录!非常感谢。我从来没有得到这样有用的建议。 –