【问题标题】:MySQL update taking(too) long timeMySQL 更新需要(太)长时间
【发布时间】:2010-12-10 07:29:17
【问题描述】:

在我们的服务出现一些预期的增长之后,突然一些更新需要很长时间,这些在表格达到大约 2MM 记录之前非常快,现在每个更新大约需要 40-60 秒。

update table1 set field1=field1+1 where id=2229230;
Query OK, 0 rows affected (42.31 sec)
Rows matched: 1  Changed: 0  Warnings: 0

以下是字段类型:

`id` bigint(20) NOT NULL auto_increment,
`field1` int(11) default '0',

分析的结果,对于上下文切换,这是唯一一个似乎在结果中具有高数字的:

mysql> show profile context switches
    -> ;
+----------------------+-----------+-------------------+---------------------+
| Status               | Duration  | Context_voluntary | Context_involuntary |
+----------------------+-----------+-------------------+---------------------+
| (initialization)     | 0.000007  |                 0 |                   0 |
| checking permissions | 0.000009  |                 0 |                   0 |
| Opening tables       | 0.000045  |                 0 |                   0 |
| System lock          | 0.000009  |                 0 |                   0 |
| Table lock           | 0.000008  |                 0 |                   0 |
| init                 | 0.000056  |                 0 |                   0 |
| Updating             | 46.063662 |             75487 |               14658 |
| end                  | 2.803943  |              5851 |                 857 |
| query end            | 0.000054  |                 0 |                   0 |
| freeing items        | 0.000011  |                 0 |                   0 |
| closing tables       | 0.000008  |                 0 |                   0 |
| logging slow query   | 0.000265  |                 2 |                   1 |
+----------------------+-----------+-------------------+---------------------+
12 rows in set (0.00 sec)

该表大约有 250 万条记录,id 是主键,并且在另一个字段上有一个唯一索引(不包括在更新中)。

这是一个 innodb 表。

关于可能是什么原因的任何指示?

任何可以帮助追踪问题的特定变量?

更新有“解释”吗?

编辑:我也刚刚注意到该表也有一个:

`modDate` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,

解释:

+----+-------------+---------------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table         | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+---------------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | table1        | const | PRIMARY       | PRIMARY | 8       | const |    1 |       |
+----+-------------+---------------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.02 sec)

【问题讨论】:

  • field1id 字段的类型是什么?
  • 您可以尝试分析此队列。见dev.mysql.com/tech-resources/articles/…
  • 看起来很奇怪 - 1 行匹配,但零行受到影响?
  • 没错,我实际上是用 field1 = field1 运行的
  • 选择需要那么长时间,还是很快?另外,硬编码新的 field1 值需要那么长时间吗?

标签: sql mysql optimization


【解决方案1】:

如果 id 确实是主键(除非您有很多很多等于 2229230 的 id?),那么查询不会花费很长时间。请运行以下两条sql并发布结果:

show create table table1;
explain select * from table1 where id = 2229230;

更新:只是为了完整,也做一个

select count(*) from table1 where id = 2229230;

【讨论】:

  • +1 如果在此信息中抛出,它肯定有助于查看是否存在不正确的表定义
【解决方案2】:

好吧,经过几个小时的追踪,似乎原因是“重复索引”,我为回答 Keith 所做的创建表有这个奇怪的组合:

  • fieldx 上的唯一键
  • fieldx 上的一个键

第二个显然是多余且无用的,但在我删除密钥后,所有更新都回到了

+1 给 Keith 和 Ivan 作为他们的 cmets 帮助我最终找到了问题。

【讨论】:

    【解决方案3】:

    我也可以推荐一下:

    OPTIMIZE TABLE table1;
    

    有时您的表只需要一点爱,如果它们增长迅速并且您有一段时间没有优化它们,那么索引可能有点疯狂。事实上,如果你有时间(而且你确实有时间),投入进去永远不会有坏处

    REPAIR TABLE table1;
    

    【讨论】:

    • 有没有办法事先知道优化或修复是否会起作用?还是运行它们是唯一的选择?
    • @webclimber - 在本地运行会告诉你。
    • 小心,来自manual重要 在执行表修复操作之前备份表;在某些情况下,该操作可能会导致数据丢失。”。
    • 万一有人偶然发现这个答案,修复表适用于 MyISAM、ARCHIVE 和 CSV 表,不适用于 InnoDB。
    【解决方案4】:

    对我有帮助的是将引擎从“innodb”更改为“myisam”。 我对类似大小数据集的更新查询从 100 毫秒变为 0.1 毫秒。

    请注意,更改现有应用程序的引擎类型可能会产生后果,因为 InnoDB 具有更好的数据完整性以及您的应用程序可能依赖的某些功能。

    对我来说,失去 InnoDB 是值得的,因为它在大型数据集上的速度提高了 1000 倍。

    【讨论】:

    • 将应用程序从 InnoDB 更改为 MyISAM 可能很危险。 MyISAM 几乎不保证数据的完整性。
    • 好点,我将在我的答案中添加这一点,如果应用程序是由设置引擎类型的人创建的,很高兴知道在某些情况下可能会牺牲数据速度的完整性。
    【解决方案5】:

    与 select 语句版本相比,在调试更新语句时需要考虑的另一件事: 更新语句是否在事务中执行?

    在我的例子中,一个事务将更新语句从极快的执行时间变成了极慢的执行时间。影响的行越多,性能损失就越大。我的陈述适用于用户定义的变量,但不知道“问题”的那一部分。

    【讨论】:

      【解决方案6】:

      我也遇到过同样的问题,结果证明是由于桌子上的触发器造成的。每当对我的表进行更新时,触发器都会更新另一个表,这实际上是导致延迟的原因。在该表上添加索引解决了这个问题。所以尝试检查表上的触发器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-17
        • 1970-01-01
        • 1970-01-01
        • 2015-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多