Dav*_*rks 6 mysql innodb profiler
使用 LOAD DATA 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)
Run Code Online (Sandbox Code Playgroud)
小智 7
mysql_load() 函数调用 open_and_lock_tables() 函数来锁定 LOAD DATA 语句中提到的表。
MySQL 获得表的排他锁,以便它可以非常快速地将数据加载到表中。LOAD DATA 过程中的开销非常小,只需进行最低限度的解析即可使其工作。
CONCURRENT 选项仅影响 MyISAM 表,如果您要加载到 InnoDB 表中,则它不允许并发访问。
System lock花费这么长时间的原因是实际数据加载被集中到了该步骤的计时中。探查器通过测量fenceposts之间的时间来工作,即为每个检测的用户功能记录进入时间。mysql_lock_tables() 函数是从 mysql_load() 内部调用的,但 mysql_load() 没有被检测,所以经过的时间从系统锁开始,到下一个栅栏柱结束,也就是查询缓存锁。
您的 196 万行数据加载大约需要 447 秒,没有任何方法可以将实际锁定时间开销与加载时间分开,因为加载没有被检测。
线程将请求或正在等待表的内部或外部系统锁。如果此状态是由外部锁请求引起的,并且您没有使用多个访问相同 MyISAM 表的 mysqld 服务器,则可以使用 --skip-external-locking 选项禁用外部系统锁。但是,默认情况下外部锁定是禁用的,因此此选项很可能不起作用。对于 SHOW PROFILE,这种状态意味着线程正在请求锁定(而不是等待它)。
这应该不足为奇,因为 InnoDB 执行行级锁定。此外,gen_clust_index(又名聚集索引)在某些时候会在主键上遇到共享锁和排他锁。
| 归档时间: |
|
| 查看次数: |
33749 次 |
| 最近记录: |