我正在从事一个涉及大量数据库写入的项目(70%的插入和30%的读取)。这个比率还包括我认为是一个读一个写的更新。读取可能是脏的(例如,在读取时我不需要100%准确的信息)。 该任务每小时将处理超过100万个数据库事务。
我在网上读了一堆关于MyISAM和InnoDB之间区别的东西,对于我将用于这个任务的特定数据库/表来说,MyISAM似乎是显而易见的选择。从我看来,InnoDB在需要事务时是很好的,因为它支持行级锁。
有人有这种负载(或更高)的经验吗?MyISAM是正确的选择吗?
我正在从事一个涉及大量数据库写入的项目(70%的插入和30%的读取)。这个比率还包括我认为是一个读一个写的更新。读取可能是脏的(例如,在读取时我不需要100%准确的信息)。 该任务每小时将处理超过100万个数据库事务。
我在网上读了一堆关于MyISAM和InnoDB之间区别的东西,对于我将用于这个任务的特定数据库/表来说,MyISAM似乎是显而易见的选择。从我看来,InnoDB在需要事务时是很好的,因为它支持行级锁。
有人有这种负载(或更高)的经验吗?MyISAM是正确的选择吗?
当前回答
我尝试在MyISAM和InnoDB表中插入随机数据。结果相当令人震惊。MyISAM插入100万行的时间比InnoDB插入1万行的时间少几秒钟!
其他回答
InnoDB offers:
ACID transactions
row-level locking
foreign key constraints
automatic crash recovery
table compression (read/write)
spatial data types (no spatial indexes)
在InnoDB中,一行中除TEXT和BLOB外的所有数据最多占用8000字节。InnoDB没有全文索引。在InnoDB中,COUNT(*)s(当WHERE, GROUP BY或JOIN不使用时)执行速度比MyISAM慢,因为行数没有存储在内部。InnoDB将数据和索引存储在一个文件中。InnoDB使用缓冲池来缓存数据和索引。
MyISAM提供:
fast COUNT(*)s (when WHERE, GROUP BY, or JOIN is not used)
full text indexing
smaller disk footprint
very high table compression (read only)
spatial data types and indexes (R-tree)
MyISAM has table-level locking, but no row-level locking. No transactions. No automatic crash recovery, but it does offer repair table functionality. No foreign key constraints. MyISAM tables are generally more compact in size on disk when compared to InnoDB tables. MyISAM tables could be further highly reduced in size by compressing with myisampack if needed, but become read-only. MyISAM stores indexes in one file and data in another. MyISAM uses key buffers for caching indexes and leaves the data caching management to the operating system.
总的来说,我推荐InnoDB用于大多数用途,MyISAM仅用于特殊用途。InnoDB现在是MySQL新版本的默认引擎。
我曾经在一个使用MySQL的大容量系统上工作过,我也尝试过MyISAM和InnoDB。
我发现MyISAM中的表级锁定对我们的工作负载造成了严重的性能问题,这听起来与您的工作负载类似。不幸的是,我还发现在InnoDB下的性能也比我希望的要差。
最后,我通过分割数据解决了争用问题,这样插入就进入了一个“热”表,而选择从不查询热表。
这也允许删除(数据是时间敏感的,我们只保留X天的价值)发生在“陈旧”的表上,这些表同样不会被选择查询触及。InnoDB在批量删除方面的性能似乎很差,所以如果你打算清除数据,你可能想要以这样一种方式来构造它,即旧数据在一个陈旧的表中,可以简单地删除而不是对其进行删除。
当然,我不知道你的应用程序是什么,但希望这能让你对MyISAM和InnoDB的一些问题有一些了解。
我知道这不会受欢迎,但我还是这么说:
myISAM缺乏对数据库基本要素的支持,如事务和引用完整性,这通常会导致应用程序出现故障/ bug。如果您的数据库引擎甚至不支持这些基础知识,那么您不可能不学习正确的数据库设计基础知识。
在数据库世界中不使用引用完整性或事务就像在软件世界中不使用面向对象编程一样。
InnoDB已经存在了,使用它吧!尽管myISAM是所有遗留系统的默认引擎,但MySQL开发人员最终还是同意在新版本中将其更改为默认引擎。
不,无论您是在读写还是有什么性能考虑,使用myISAM都会导致各种各样的问题,比如我刚刚遇到的这个问题:我正在执行数据库同步,同时其他人访问了一个访问myISAM表的应用程序。由于缺乏事务支持,这个引擎的可靠性也很差,导致整个数据库崩溃,我不得不手动重启mysql!
在过去15年的开发中,我使用了许多数据库和引擎。在此期间,myISAM在我身上崩溃了十几次,其他数据库只有一次!那是一个microsoft SQL数据库,其中一些开发人员编写了错误的CLR代码(公共语言运行时-基本上是在数据库内部执行的c#代码),顺便说一下,这并不是数据库引擎的错误。
我同意这里的其他答案,即高质量的高可用性、高性能应用程序不应该使用myISAM,因为它不起作用,它不够健壮或不够稳定,无法带来无挫折的体验。详见Bill Karwin的回答。
附注:我喜欢myISAM的粉丝们投反对票,但不能告诉你这个答案的哪一部分是错误的。
底线:如果你离线工作,选择大量的数据,MyISAM可能会给你更好的(好得多)速度。
在某些情况下,MyISAM比InnoDB的效率要高得多:离线操作大型数据转储时(因为表锁)。
示例:我正在从NOAA转换一个csv文件(15M条记录),它使用VARCHAR字段作为键。InnoDB的运行时间很长,即使有大量的内存可用。
这是CSV的一个例子(第一个和第三个字段是键)。
USC00178998,20130101,TMAX,-22,,,7,0700
USC00178998,20130101,TMIN,-117,,,7,0700
USC00178998,20130101,TOBS,-28,,,7,0700
USC00178998,20130101,PRCP,0,T,,7,0700
USC00178998,20130101,SNOW,0,T,,7,
因为我需要做的是运行观察到的天气现象的批量离线更新,我使用MyISAM表接收数据,并在键上运行join,这样我就可以清理传入的文件,并将VARCHAR字段替换为INT键(与原始VARCHAR值存储的外部表相关)。
有点偏离主题,但为了文档的目的和完整性,我想添加以下内容。
一般来说,使用InnoDB会使应用程序变得不那么复杂,可能也更没有bug。因为可以将所有引用完整性(外键约束)放入数据模型中,所以不需要像使用MyISAM时那样多的应用程序代码。
Every time you insert, delete or replace a record, you will HAVE to check and maintain the relationships. E.g. if you delete a parent, all children should be deleted too. For instance, even in a simple blogging system, if you delete a blogposting record, you will have to delete the comment records, the likes, etc. In InnoDB this is done automatically by the database engine (if you specified the contraints in the model) and requires no application code. In MyISAM this will have to be coded into the application, which is very difficult in web-servers. Web-servers are by nature very concurrent / parallel and because these actions should be atomical and MyISAM supports no real transactions, using MyISAM for web-servers is risky / error-prone.
而且在大多数情况下,InnoDB会表现得更好,原因有很多,其中一个原因是它能够使用记录级锁而不是表级锁。不仅在写比读更频繁的情况下,在大型数据集上有复杂连接的情况下也是如此。我们注意到,对于非常大的连接(需要几分钟),使用InnoDB表比MyISAM表性能提高了3倍。
我想说的是,在使用MySQL时,InnoDB(使用3NF数据模型,具有引用完整性)应该是默认的选择。MyISAM只能在非常具体的情况下使用。它很可能会执行更少,导致应用程序更大,bug更多。
话虽如此。数据模型是一门很少在网页设计师/程序员中发现的艺术。无意冒犯,但这确实解释了MyISAM被如此广泛使用的原因。