使用LOAD数据INFILE插入innodb的2M行耗时7.5分钟,而分析显示99%的时间处于“系统锁”中。
这能告诉我什么有用的东西吗?
mysql> set profiling=1;
Query OK, 0 rows affected (0.00 sec)
mysql> LOAD DATA CONCURRENT LOCAL INFILE '/tmp/item' REPLACE INTO TABLE item_load;
Query OK, 1964807 rows affected, 8 warnings (7 min 27.35 sec)
Records: 1964806 Deleted: 1 Skipped: 0 Warnings: 8
mysql> show profile for query 1;
+------------------------------+------------+
| Status | Duration |
+------------------------------+------------+
| starting | 0.000206 |
| checking permissions | 0.000015 |
| Opening tables | 0.000034 |
| System lock | 447.327523 |
| Waiting for query cache lock | 0.000352 |
| query end | 0.000011 |
| closing tables | 0.000014 |
| freeing items | 0.000033 |
| logging slow query | 0.000007 |
| logging slow query | 0.000006 |
| cleaning up | 0.000006 |
+------------------------------+------------+
11 rows in set (0.02 sec)发布于 2013-01-12 03:53:50
线程将请求或正在等待表的内部或外部系统锁。如果此状态是由外部锁请求引起的,并且您没有使用访问相同MyISAM表的多个mysqld服务器,则可以使用--跳过外部锁定选项禁用外部系统锁。但是,默认情况下,外部锁定是禁用的,因此此选项很可能没有任何效果。对于显示概要文件,此状态意味着线程正在请求锁(而不是等待它)。
这并不奇怪,因为InnoDB会进行行级锁定。此外,gen将在某个时候体验主键上的共享和独占锁。
发布于 2015-02-05 19:47:23
mysql_load()函数调用open_and_lock_tables()函数来锁定LOAD数据语句中提到的表。
MySQL获取表上的独占锁,以便能够非常迅速地将数据加载到表中。负载数据过程中的开销很小,只需要进行最低限度的解析即可使其工作。
并发选项只影响MyISAM表,如果要加载到InnoDB表,则不允许并发访问。
系统锁花了这么长时间的原因是,实际的数据负载被集中到了这一步的时间中。分析器通过测量fencepost之间的时间来工作,即记录每个已检测的用户函数的输入时间。mysql_lock_tables()函数是从mysql_load()内部调用的,但是mysql_load()没有被检测,因此经过的时间从系统锁开始,到下一个fencepost结束,这就是查询缓存锁。
您的1.96万行的数据加载大约需要447秒,没有任何方法将实际的锁时间开销与加载时间分开,因为加载没有被检测。
https://dba.stackexchange.com/questions/31823
复制相似问题