【问题标题】:Slow MySQL query on update statement更新语句上的缓慢 MySQL 查询
【发布时间】:2013-11-24 14:11:48
【问题描述】:

我正在尝试将一些数据从一个数据库移动到另一个数据库。我目前在我的数据库中有超过一百万个条目,我预计这需要很长时间,但已经过了 50 分钟并且没有结果:)。 这是我的查询:

UPDATE xxx.product AS p 
LEFT JOIN xx.tof_art_lookup AS l ON p.model_view = l.ARL_SEARCH_NUMBER 
SET p.model = l.ARL_DISPLAY_NR 
WHERE p.model_view = l.ARL_SEARCH_NUMBER;

欢迎任何有关如何改进此查询的帮助。提前致谢!

【问题讨论】:

  • 在更新中使用 Join 非常消耗!
  • 更新时的外连接非常罕见(除了 IS NULLS)。你确定那是你想要的吗?如果没有,请切换到 INNER JOIN。
  • 您是否建议使用 php 获取数据并将其保存到数组中,然后执行更新?
  • 50 分钟?如果您有一百万行,则每秒更新 300 次。挂在那里。这样的工作可能需要一夜之间。此外,您需要让我们知道您是否使用 InnoDB。
  • 不要将数据带到 PHP 中。

标签: mysql sql performance


【解决方案1】:

找出导致缓慢的原因。

检查 JOIN 是否优化

只运行 SELECT:

SELECT COUNT(*)
FROM xxx.product p LEFT JOIN xx.tof_art_lookup l 
  ON p.model_view = l.ARL_SEARCH_NUMBER;

需要多长时间?并且EXPLAIN SELECT ... 检查正确的INDEX 用于JOIN。

如果 JOIN 一切正常,则更新行很慢。这种情况很难让事情变得更快。

更新 = 删除和插入

我没试过这个。但有时,这种策略更快。UPDATE 是删除旧行并使用新值插入新行。

// CREATE new table and INSERT
CREATE TABLE xxx.new_product
SELECT p.model_model, l. ARL_DISPLAY_NR, ... 
FROM xxx.product p LEFT JOIN xx.tof_art_lookup l 
  ON p.model_view = l.ARL_SEARCH_NUMBER;

// drop xxx.procuct
// rename xxx.new_product to xxx.product

将表分成小块,并发运行

我认为你的工作是 CPU 受限的,而你的 UPDATE 查询只使用一个 CPU 不能让多个内核受益。 xxx.product TABLE 没有 join 约束,有 1M 行顺序更新

我的建议如下。

给xxx.product一些条件,让xxx.product分成20组。 (我不知道哪个专栏更适合你,因为我没有关于 xxx.product 的信息)

然后同时运行 20 个查询。

例如:

// for 1st chunk
UPDATE xxx.product AS p 
...
WHERE p.model_view = l.ARL_SEARCH_NUMBER
  AND p.column BETWEEN val1 AND val2; <= this condition spliting xxx.product

// for 2nd chunk
UPDATE xxx.product AS p 
...
WHERE p.model_view = l.ARL_SEARCH_NUMBER
  AND p.column BETWEEN val2 AND val3;

...
...

// for 20th chunk
UPDATE xxx.product AS p 
...
WHERE p.model_view = l.ARL_SEARCH_NUMBER
  AND p.column BETWEEN val19 AND val20;

找到 BETWEEN 值均匀分布表很重要。直方图可以帮助你。 Getting data for histogram plot

【讨论】:

  • 感谢您的帮助。我会试一试,看看是什么花了这么长时间。
  • @Ionut Laurentiu 我期待您的回复!即使我的建议没有改善您的查询。
【解决方案2】:

p.model_view 上的索引,l.ARL_SEARCH_NUMBER,如果你不想摆脱 JOIN。
实际上,它可能会根据实际数据量及其值(NULL 存在)通过使用进行优化:
1. 监控查询执行计划,如果不好,则为编译器提供查询提示或为子查询交换 JOIN,以便编译器在其中使用另一种类型的连接(合并/嵌套循环/哈希/其他)
2. 制作逻辑更复杂但速度更快的存储过程
3. 小部分更新

【讨论】:

  • 感谢您的帮助。我会试着看看什么需要这么长时间,并会回来更新或希望关闭这个线程:D
猜你喜欢
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
  • 2013-10-05
  • 2018-06-14
  • 1970-01-01
相关资源
最近更新 更多