MySQL 更新连接性能

Posted

技术标签:

【中文标题】MySQL 更新连接性能【英文标题】:MySQL update join performance 【发布时间】:2015-07-29 08:04:56 【问题描述】:

我需要根据另一个表中的列更新一个表中的多个列。首先,我只是更新其中一个。我尝试了 2 种方法,这两种方法都有效,但使用 mysql 命令大约需要 4 分钟,而在 php 中运行时需要 20 多分钟。这两个表的长度约为 20,000 行。

我的问题是,有没有更好或更有效的方法?

方法一:

   UPDATE table_a,table_b 
   SET table_a.price = table_b.price 
   WHERE table_a.product_code=table_b.product_code

方法二:

   UPDATE table_a INNER JOIN table_b 
   ON table_a.product_code = table_b.product_code
   SET table_a.price=table_b.price

我猜这些基本上以相同的方式工作,但我认为连接会更有效。 product_code 列是随机文本,尽管它是唯一的,并且每一行都与另一个表中的一个匹配。

还有什么我可以尝试的吗?

谢谢

更新:这已通过创建索引来解决,例如

    CREATE UNIQUE INDEX index_code on table_a (product_code)
    CREATE UNIQUE INDEX index_code on table_b (product_code)

【问题讨论】:

您的 ID 列是否已编入索引? 它们都是一样的。在第一个查询上运行 EXPLAIN EXTENDED,然后是 SHOW WARNINGS; 它们并不完全相同,因为其中一个是设置 id,另一个是设置价格。隐式和显式连接语法在性能上没有区别 抱歉来晚了,他们都定了价格,上面已经编辑过了。所以他们都匹配了ID,然后在table_a中从table_b设置价格。 @fbas 索引提示是我所需要的(在 SQL 课程上还没有那么远!) - 创建和更新时间从 4 分钟缩短到不到 1 秒。谢谢 【参考方案1】:

如果您的查询运行缓慢,您将不得不检查查询正在使用的数据。

您的查询如下所示:

UPDATE table_a INNER JOIN table_b 
ON table_a.product_code = table_b.product_code
SET table_a.price=table_b.price

为了看看你可以做的延迟在哪里

EXPLAIN SELECT a.price, b.price FROM table_b b
INNER JOIN table_a a ON (a.product_code = b.product_code)

这将告诉您是否正在使用索引,请参阅 the info on EXPLAIN 和 more info here。

在您的情况下,您没有任何索引 (possible keys = null) 强制 MySQL 进行全表扫描。

当速度很慢时,您应该始终对查询执行explain select。您必须将非选择查询转换为select,但这并不难,只需在选择子句中列出所有更改的字段,然后照原样复制joinwhere 子句即可。

【讨论】:

以上是关于MySQL 更新连接性能的主要内容,如果未能解决你的问题,请参考以下文章

扩展 MySQL 数据库,提高许多连接的性能

Python 使用 PyMysqlDBUtils 创建连接池提升性能

Mysql:视图与循环表连接

Python mysql连接池

JDBC连接池性能对比

高性能mysql第一章——架构