【问题标题】:MySQL Process List - improve performance - lock issueMySQL进程列表-提高性能-锁定问题
【发布时间】:2011-12-03 01:36:26
【问题描述】:

SHOW PROCESSLIST - 它显示大约 30+ 行已被锁定几秒钟然后更新。

有没有办法加快更新速度?

例子:

+------+-----------------+-----------+----------------+---------+------+----------+-------------------------------------------------------------------------------
| Id   | User            | Host      | db             | Command | Time | State    | Info                                                                          
+------+-----------------+-----------+----------------+---------+------+----------+--------------------------------------------------------------------------------
|  265 | user            | localhost | xxxxxxxxxxxxxx | Query   |   15 | Updating | UPDATE data SET status = '1', error = 'Unknown error'  WHERE f= 0xxxxx    
|  269 | user            | localhost | xxxxxxxxxxxxxx | Query   |   17 | Updating | UPDATE data SET status = '1', error = 'Invalid ....'  WHERE f= 0xxx 
|  280 | user            | localhost | xxxxxxxxxxxxxx | Query   |    7 | Updating | UPDATE data SET status = 1  WHERE f = 0xxxx                                           
|  300 | user            | localhost | xxxxxxxxxxxxxx | Query   |    1 | Updating | UPDATE data SET status = '1', error = 'Unknown ....'  WHERE f= 0xx             
|  314 | user            | localhost | xxxxxxxxxxxxxx | Query   |   13 | Updating | UPDATE data SET status = '1', error = 'Invalid....'  WHERE f= 0xxxx
|  327 | user            | localhost | xxxxxxxxxxxxxx | Query   |   11 | Updating | UPDATE data SET status = '1', error = 'Unknown ....'  WHERE f= 0xxxx               
|  341 | user            | localhost | xxxxxxxxxxxxxx | Sleep   |    2 |          | NULL                                                                                        
|  350 | user            | localhost | xxxxxxxxxxxxxx | Query   |    7 | Updating | UPDATE data SET status = '1', error = 'Unknown ....'  WHERE f= 0xxx                
|  360 | user            | localhost | xxxxxxxxxxxxxx | Query   |    5 | Updating | UPDATE data SET status = 1  WHERE f = 0xxxx     

有很多 UPDATE - 我使用的是InnoDB,一些字段是index

在数据表中,有超过 500,000 行需要更新,同时它在 PHP CLI 脚本中循环(在 Linux 中在后台/进程中运行)。

【问题讨论】:

    标签: php mysql sql database innodb


    【解决方案1】:
    • 确保 f 列已编入索引,以便 WHERE 子句使用它。否则,您将针对每个 UPDATE 扫描整个表。

    • 尝试对更新进行分组,这样您就可以使用一个 UPDATE 设置多行,而不是一次一行。

    • 确保您没有使用自动提交。尝试对每个事务执行多项更改。

    • 确保您已调整 InnoDB。大多数人使用innodb_buffer_pool_sizeinnodb_log_file_sizeinnodb_io_capacity 的默认值。默认值未针对高性能进行调整。

    • 按照@Paulo H. 的建议,设置 innodb_flush_log_at_trx_commit=2 以减少 fsync。

    【讨论】:

      【解决方案2】:

      InnoDB 在每个 INSERT/UPDATE 中使用 IO 来确保 de ACID 属性,您可以将这种定义 innodb_flush_log_at_trx_commit 变量的行为更改为 2,因此 MySQL 每秒使用 IO 而不是每次提交(在许多情况下都很好)。

      更多信息here

      【讨论】:

        【解决方案3】:

        一个快速的解决方法是战略性地添加一个 sleep() 调用,这样当您逐步浏览数千行时,您就不会压倒数据库。一个好的做法是每行睡 1/100 秒,然后每 100 行睡整整 5 秒。这是我参与的系统的一般规则,因此您可能需要稍微修改这些设置才能让它们为您工作。

        我担心的一个问题是您的用户表存储错误列的文本值。文本列的性能不如 int 列,更不用说如果您需要更新错误值,可能会影响数千条记录。

        【讨论】:

        • while loop 中,我有sleep(2) 在它进入下一次迭代之前。您提到每 100 行执行 5 秒 - 我会检查一下,但它会起作用吗?嗯
        【解决方案4】:

        InnoDB 是正确的引擎,因为它锁定了行,而不是整个表。我建议确保您已正确索引您的表,您正在使用正确的列类型,并且它们尽可能小(因此,真或假的东西应该存储为 unsigned整数 1).

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-08
          • 2016-04-29
          • 1970-01-01
          • 2016-10-07
          相关资源
          最近更新 更多