Cha*_*tin 7 mysql innodb myisam mysqldump performance
好吧,这可能是三个问题。我想将使用 MyISAM 的现有 MySQL 5.1 数据库移动到使用 InnoDB 的 5.6,因为我认为有很多明显的 - 甚至可能是好的 - 原因。
这是在 Amazon RDS 上,所以我的升级路线仅限于转储和重新创建数据库。
我会欣然承认我不是一个老练的 DBA。
大约需要 15 分钟 mysqldump
我们的 1.6 亿多行。(表演桌等来了,抱紧你的马。)
花了大约 50 个小时加载到 mysql 5.6 实例中,并且引擎巧妙地将 sed-script-ed 加载到 InnoDB。
select count(*) from node;
在目前的 DB 上给出了大约 1.62 亿。在5.6上,它给出了大约9300万。加载似乎是成功的,尽管我无法证明;至少,加载终止后没有错误消息。
如果它不成功,那真的慢。
因此,select count(*) from node;
在 5.1 上几乎没有任何时间完成——查询结果在 0.00 到 0.03 秒之间。在使用 InnoDB 的 5.6 上,这需要一分钟多的时间。解释清楚地表明这是因为查询优化的方式不同——但不清楚为什么不同。
mysql> show create table node\G
*************************** 1. row ***************************
Table: node
Create Table: CREATE TABLE `node` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`graph` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
`subject` varchar(200) NOT NULL,
`predicate` varchar(200) NOT NULL,
`object` mediumtext NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `nodeindex` (`graph`(20),`subject`(100),`predicate`(100),`object`(100)),
KEY `ix_node_subject` (`subject`),
KEY `ix_node_graph` (`graph`),
KEY `ix_node_object` (`object`(255)),
KEY `ix_node_predicate` (`predicate`),
KEY `node_po` (`predicate`,`object`(130)),
KEY `node_so` (`subject`,`object`(130)),
KEY `node_sp` (`subject`,`predicate`(130)),
FULLTEXT KEY `node_search` (`object`)
) ENGINE=MyISAM AUTO_INCREMENT=550671861 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> select count(id) from node;
+-----------+
| count(id) |
+-----------+
| 163426434 |
+-----------+
1 row in set (0.00 sec)
mysql> explain select count(id) from node;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
mysql> show create table node\G
*************************** 1. row ***************************
Table: node
Create Table: CREATE TABLE `node` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`graph` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
`subject` varchar(200) NOT NULL,
`predicate` varchar(200) NOT NULL,
`object` mediumtext NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `nodeindex` (`graph`(20),`subject`(100),`predicate`(100),`object`(100)),
KEY `ix_node_subject` (`subject`),
KEY `ix_node_graph` (`graph`),
KEY `ix_node_object` (`object`(255)),
KEY `ix_node_predicate` (`predicate`),
KEY `node_po` (`predicate`,`object`(130)),
KEY `node_so` (`subject`,`object`(130)),
KEY `node_sp` (`subject`,`predicate`(130)),
FULLTEXT KEY `node_search` (`object`)
) ENGINE=InnoDB AUTO_INCREMENT=481239575 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
``
mysql> explain select count(id) from node;
+----+-------------+-------+-------+---------------+---------------+---------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------------+---------+------+----------+-------------+
| 1 | SIMPLE | node | index | NULL | ix_node_graph | 103 | NULL | 79671827 | Using index |
+----+-------------+-------+-------+---------------+---------------+---------+------+----------+-------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
您的问题与 MySQL 版本无关。它与存储引擎有关。
运行 mysqldump 只涉及来自 .MYD
MyISAM 表文件的。因此,我认为在 15 分钟内转储 1.63 亿行并不奇怪。
将数据加载到 Amazon RDS 需要 50 个小时,这对我来说也不令人震惊。为什么 ?
无论您为 MySQL RDS 选择哪种服务器模型,InnoDB 事务日志(ib_logfile0、ib_logfile1)始终为 128M,并且不允许更改,甚至RDS CLI也不行。我之前写过这个:本地数据库 vs 亚马逊 RDS
所有对 InnoDB 的写入都写入双写缓冲区>您应该在加载之前禁用它:请参阅我的帖子加速 InnoDB 插入和更新的可能性
来自每个 INSERT 的每个行块都作为一个事务处理,其中的内容通过 ibdata1 的双写缓冲区和事务日志写入。因此,缓慢。
看看nodeindex
. 我可以看到它是一个前缀索引。
前缀支持和前缀长度(如果支持)取决于存储引擎。例如,MyISAM 表的前缀最长可达 1000 字节,InnoDB 表的前缀最长可达 767 字节。
我几乎可以保证长度graph,subject,predicate,object
超过 767 的任何行都不会进入 InnoDB 表。
这是由于存储引擎。
当你select count(id) from node;
对抗 MyISAM 时,MyISAM 会作弊并进入.MYD
标题以获取行数。因此,获取行数的运行时间不是实际行数的函数。这就是 MySQL 查询优化器优化所有标准机制并为您提供行计数的方式。
说到 InnoDB,因为它不存储行数,所以每次都必须完全扫描一个表:请参阅我的帖子为什么 InnoDB 不存储行数?
我不会将它导入为 InnoDB。我会先导入 MyISAM。然后,将所有 MyISAM 表转换为 InnoDB。在转换它之前,您可能必须更改nodeindex
或完全摆脱它。否则,您将在转换时丢失行。
看我的帖子哪个先:升级mysql版本还是转换存储引擎?想要查询更多的信息。
归档时间: |
|
查看次数: |
6340 次 |
最近记录: |