MySQL进程列表 - 提高性能 - 锁定问题

时间:2011-12-03 01:36:26

标签: php mysql sql database innodb

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     

有很多更新 - 我使用的是InnoDB,有些字段是index

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

4 个答案:

答案 0 :(得分:1)

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

更多信息here

答案 1 :(得分:1)

  • 确保f列已编入索引,以便WHERE子句正在使用它。否则,您将在每次更新时扫描整个表格。

  • 尝试对更新进行分组,以便您可以一次设置一行UPDATE而不是一行。

  • 确保您没有使用自动提交。尝试每次交易执行多项更改。

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

  • 设置innodb_flush_log_at_trx_commit=2以减少fsyncs,正如@Paulo H.建议的那样。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

InnoDB是您正在执行的操作的正确引擎,因为它会锁定行,而不是整个表。我建议您确保已正确索引表格,使用正确的列类型并且它们的大小与它们所需的一样小(因此,无论是真还是假,都应将其存储为 unsigned int 1 )。

相关问题