我正在从事一个涉及大量数据库写入的项目(70%的插入和30%的读取)。这个比率还包括我认为是一个读一个写的更新。读取可能是脏的(例如,在读取时我不需要100%准确的信息)。 该任务每小时将处理超过100万个数据库事务。
我在网上读了一堆关于MyISAM和InnoDB之间区别的东西,对于我将用于这个任务的特定数据库/表来说,MyISAM似乎是显而易见的选择。从我看来,InnoDB在需要事务时是很好的,因为它支持行级锁。
有人有这种负载(或更高)的经验吗?MyISAM是正确的选择吗?
我正在从事一个涉及大量数据库写入的项目(70%的插入和30%的读取)。这个比率还包括我认为是一个读一个写的更新。读取可能是脏的(例如,在读取时我不需要100%准确的信息)。 该任务每小时将处理超过100万个数据库事务。
我在网上读了一堆关于MyISAM和InnoDB之间区别的东西,对于我将用于这个任务的特定数据库/表来说,MyISAM似乎是显而易见的选择。从我看来,InnoDB在需要事务时是很好的,因为它支持行级锁。
有人有这种负载(或更高)的经验吗?MyISAM是正确的选择吗?
当前回答
我曾经在一个使用MySQL的大容量系统上工作过,我也尝试过MyISAM和InnoDB。
我发现MyISAM中的表级锁定对我们的工作负载造成了严重的性能问题,这听起来与您的工作负载类似。不幸的是,我还发现在InnoDB下的性能也比我希望的要差。
最后,我通过分割数据解决了争用问题,这样插入就进入了一个“热”表,而选择从不查询热表。
这也允许删除(数据是时间敏感的,我们只保留X天的价值)发生在“陈旧”的表上,这些表同样不会被选择查询触及。InnoDB在批量删除方面的性能似乎很差,所以如果你打算清除数据,你可能想要以这样一种方式来构造它,即旧数据在一个陈旧的表中,可以简单地删除而不是对其进行删除。
当然,我不知道你的应用程序是什么,但希望这能让你对MyISAM和InnoDB的一些问题有一些了解。
其他回答
对于一个有更多写和读的负载,你将受益于InnoDB。因为InnoDB提供的是行锁而不是表锁,所以你的select可以是并发的,不仅仅是彼此之间的select,还有许多insert。但是,除非你打算使用SQL事务,否则将InnoDB提交刷新设置为2 (innodb_flush_log_at_trx_commit)。这将为您提供大量原始性能,否则将表从MyISAM转移到InnoDB时会损失这些性能。
Also, consider adding replication. This gives you some read scaling and since you stated your reads don't have to be up-to-date, you can let the replication fall behind a little. Just be sure that it can catch up under anything but the heaviest traffic or it will always be behind and will never catch up. If you go this way, however, I strongly recommend you isolate reading from the slaves and replication lag management to your database handler. It is so much simpler if the application code does not know about this.
最后,要注意不同的表负载。您不会在所有表上都有相同的读/写比率。一些接近100%读取的小表可以负担得起MyISAM。同样地,如果你有一些接近100%写的表,你可能会受益于INSERT DELAYED,但这只在MyISAM中支持(对于InnoDB表,DELAYED子句会被忽略)。
但基准是肯定的。
根据我的经验,MyISAM是一个更好的选择,只要你不做delete、update、大量的单个INSERT、事务和全文索引。顺便说一句,CHECK TABLE太可怕了。随着表的行数越来越老,你不知道它什么时候会结束。
如果它是70%的插入和30%的读取,那么它更像是在InnoDB端。
我曾经在一个使用MySQL的大容量系统上工作过,我也尝试过MyISAM和InnoDB。
我发现MyISAM中的表级锁定对我们的工作负载造成了严重的性能问题,这听起来与您的工作负载类似。不幸的是,我还发现在InnoDB下的性能也比我希望的要差。
最后,我通过分割数据解决了争用问题,这样插入就进入了一个“热”表,而选择从不查询热表。
这也允许删除(数据是时间敏感的,我们只保留X天的价值)发生在“陈旧”的表上,这些表同样不会被选择查询触及。InnoDB在批量删除方面的性能似乎很差,所以如果你打算清除数据,你可能想要以这样一种方式来构造它,即旧数据在一个陈旧的表中,可以简单地删除而不是对其进行删除。
当然,我不知道你的应用程序是什么,但希望这能让你对MyISAM和InnoDB的一些问题有一些了解。
我认为这是一篇很好的文章,解释了两者之间的区别,以及什么时候应该使用其中一种: http://tag1consulting.com/MySQL_Engines_MyISAM_vs_InnoDB