【问题标题】:Using MySQL to run update on a large table is very slow使用 MySQL 在大表上运行更新非常慢
【发布时间】:2013-06-27 04:36:13
【问题描述】:

我正在使用 UPDATE 通过将 m2 匹配到 n1 来填充 m3 中的缺失值,在 n2 中找到相应的值,并将其插入到 m3 中。表 mmm 有 250 万行,表 nnn 有 55,000 行。

以下两个查询都有效,但问题在于性能。现在,我正在以零碎的方式更新 mmm。我已将 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

【问题讨论】:

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

标签: mysql performance database-design database-performance


【解决方案1】:

您可以在查询前使用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

【讨论】:

  • 你说的我都做了,效果很好。 (创建主键有帮助,但重要的变化是在 m2 中创建索引。)我能够在不到 20 秒的时间内更新 mmm 中的 250 万条记录与 nnn 中的所有 50k 记录!太感谢了。我从来没有得到过这么有用的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-27
  • 2021-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-22
  • 1970-01-01
相关资源
最近更新 更多