数据库管理系统

数据库管理系统

我有一张大约有 10 亿行的表,其中 98% 是读取密集型的。

我尝试使用不同的存储引擎(MyISAM 和 InnoDB)来调整数据库

然后运行了一些测试来查看性能

在 where 子句中我有一个主键 ID,而且由于 MyISAM Ke​​y Cache 存储加载其缓冲区中的所有索引,因此使用 MyISAM 似乎相当快,比 InnoDB 快 2 倍左右

但是对于 InnoDB 来说,它似乎更慢!!是不是因为 InnoDB 不使用任何缓冲区来预加载索引?

答案1

在决定使用 MyISAM 还是 InnoDB 之前,你必须了解这两种存储引擎各自的缓存方式

数据库管理系统

读取时,MyISAM 表的索引可以从 .MYI 文件中读取一次,并加载到 MyISAM 密钥缓存中(大小由密钥缓冲区大小)。如何让 MyISAM 表的 .MYD 读取速度更快?使用这个:

ALTER TABLE mytable ROW_FORMAT=Fixed;

我之前的帖子里写过这个

数据库引擎InnoDB

好的,那么 InnoDB 呢?InnoDB 会为查询执行任何磁盘 I/O 吗?令人惊讶的是,它确实会执行!你可能认为我这样说很疯狂,但这绝对是真的,即使对于 SELECT 查询. 此时,您可能会想“InnoDB 究竟是如何执行查询的磁盘 I/O 的?”

这一切都要追溯到 InnoDB 是一个-complaint 事务存储引擎。为了使 InnoDB 成为事务型,它必须支持 in IACID即隔离性。维护事务隔离的技术是通过MVCC,多版本并发控制简单来说,InnoDB 记录事务尝试更改数据之前的数据。这些数据记录在哪里?在系统表空间文件中,也就是众所周知的 ibdata1。这需要磁盘 I/O

比较

由于 InnoDB 和 MyISAM 都执行磁盘 I/O,那么哪些随机因素决定了谁更快?

  • 列的大小
  • 列格式
  • 字符集
  • 数值范围(需要足够大的 INT)
  • 行被拆分到多个块中(行链接)
  • 数据碎片化导致DELETEsUPDATEs
  • 主键的大小(InnoDB 有一个聚集索引,需要两次键查找)
  • 索引条目的大小
  • 名单还在继续……

结语

因此,在高读取率环境中,如果 ibdata1 中包含的撤消日志中写入的数据足够多,以支持对 InnoDB 数据施加的事务行为,则具有固定行格式的 MyISAM 表可能比 InnoDB 从 InnoDB 缓冲池读取的性能更好。请仔细规划您的数据类型、查询和存储引擎。一旦数据增长,移动数据可能会变得非常困难。

顺便说一句,我五天前写过类似的东西:如何为 mySQL 指定内存限制?

答案2

当没有数据争用时,MyISAM 的运行速度总是比 innodb 快得多。开始添加多个会话尝试更新同一张表,innodb 很快就会获得性能优势。

如何针对两个引擎调整系统非常不同的。

存在不同引擎的原因是因为存在不同的工作负载/访问模式。

答案3

您必须“热身” innodb。例如通过重新播放访问日志或运行一些将触及索引中每个值的智能查询。

看一看这里或者这里

我希望您不要使用 innodb 的默认 mysql 设置 - 它们适用于~2000 的硬件。

答案4

在 MariaDB 上进一步调整 InnoDB 后,我增加了innodb_buffer_pool_sizeInnoDB 数据库的大小,这样做之后,InnoDB 开始更快地获取行

我认为根据你的数据库需求调整 InnoDB 非常重要

相关内容