我有一张大约有 10 亿行的表,其中 98% 是读取密集型的。
我尝试使用不同的存储引擎(MyISAM 和 InnoDB)来调整数据库
然后运行了一些测试来查看性能
在 where 子句中我有一个主键 ID,而且由于 MyISAM Key Cache 存储加载其缓冲区中的所有索引,因此使用 MyISAM 似乎相当快,比 InnoDB 快 2 倍左右
但是对于 InnoDB 来说,它似乎更慢!!是不是因为 InnoDB 不使用任何缓冲区来预加载索引?
答案1
在决定使用 MyISAM 还是 InnoDB 之前,你必须了解这两种存储引擎各自的缓存方式
数据库管理系统
读取时,MyISAM 表的索引可以从 .MYI 文件中读取一次,并加载到 MyISAM 密钥缓存中(大小由密钥缓冲区大小)。如何让 MyISAM 表的 .MYD 读取速度更快?使用这个:
ALTER TABLE mytable ROW_FORMAT=Fixed;
我之前的帖子里写过这个
Sep 20, 2011
:https://dba.stackexchange.com/questions/5974/best-of-myisam-and-innodb/6008#6008(请先阅读此文)May 10, 2011
: https://dba.stackexchange.com/questions/2640/what-is-the-performance-impact-of-using-char-vs-varchar-on-a-fixed-size-field/2643#2643(权衡#2)Aug 12, 2011
:https://dba.stackexchange.com/questions/4576/which-dbms-is-good-for-super-fast-reads-and-a-simple-data-structure/4589#4589(第 3 段)Jan 03, 2012
:https://dba.stackexchange.com/questions/10069/optimized-my-cnf-for-high-end-and-busy-server/10080#10080(在标题复制)
数据库引擎InnoDB
好的,那么 InnoDB 呢?InnoDB 会为查询执行任何磁盘 I/O 吗?令人惊讶的是,它确实会执行!你可能认为我这样说很疯狂,但这绝对是真的,即使对于 SELECT 查询. 此时,您可能会想“InnoDB 究竟是如何执行查询的磁盘 I/O 的?”
这一切都要追溯到 InnoDB 是一个酸-complaint 事务存储引擎。为了使 InnoDB 成为事务型,它必须支持 in I
,ACID
即隔离性。维护事务隔离的技术是通过MVCC,多版本并发控制简单来说,InnoDB 记录事务尝试更改数据之前的数据。这些数据记录在哪里?在系统表空间文件中,也就是众所周知的 ibdata1。这需要磁盘 I/O。
比较
由于 InnoDB 和 MyISAM 都执行磁盘 I/O,那么哪些随机因素决定了谁更快?
- 列的大小
- 列格式
- 字符集
- 数值范围(需要足够大的 INT)
- 行被拆分到多个块中(行链接)
- 数据碎片化导致
DELETEs
的UPDATEs
- 主键的大小(InnoDB 有一个聚集索引,需要两次键查找)
- 索引条目的大小
- 名单还在继续……
结语
因此,在高读取率环境中,如果 ibdata1 中包含的撤消日志中写入的数据足够多,以支持对 InnoDB 数据施加的事务行为,则具有固定行格式的 MyISAM 表可能比 InnoDB 从 InnoDB 缓冲池读取的性能更好。请仔细规划您的数据类型、查询和存储引擎。一旦数据增长,移动数据可能会变得非常困难。
顺便说一句,我五天前写过类似的东西:如何为 mySQL 指定内存限制?
答案2
当没有数据争用时,MyISAM 的运行速度总是比 innodb 快得多。开始添加多个会话尝试更新同一张表,innodb 很快就会获得性能优势。
如何针对两个引擎调整系统非常不同的。
存在不同引擎的原因是因为存在不同的工作负载/访问模式。
答案3
答案4
在 MariaDB 上进一步调整 InnoDB 后,我增加了innodb_buffer_pool_size
InnoDB 数据库的大小,这样做之后,InnoDB 开始更快地获取行
我认为根据你的数据库需求调整 InnoDB 非常重要