我有一个很大的MySQL表(大约1000万行,6.5G)我用它来读取和读取写。它是MyISAM,由于MyISAM对写入的所有表锁定,我得到了很多锁。
我决定尝试转移到推荐用于读/写表的InnoDB,它只会锁定写入时的特定行。
转换后,我测试了插入语句,结果表明它在InnoDB表中比在MyISAM表中多花了15倍(从0.1秒到1.5秒)。那是为什么?
我还没有为InnoDB配置任何东西,并且还计划添加分区,但这个数字对我来说仍然是意料之外的。当然这些表是相同的,相同的索引等。
根据要求提供的其他信息:
2个索引。 primary是Big INT类型的data_id,varchar(255)类型的非唯一user_id。
插入大约150行,具有相同的user_id。
索引大小:MyISAM为200 MB,InnoDB为400 MB
答案 0 :(得分:5)
related answer表明,当写入与读取的比率相对较高时,将innodb_flush_log_at_trx_commit
变量设置为2可能会提高性能。有关详情,请参阅the documentation。
答案 1 :(得分:4)
我认为,InnoDB实现了真正的ACID,并且做了很多fsync()
来保存数据。并且MyISAM不是真正的ACID并且fsync()更少。
There are recomendations to kill fsync
If you want to load data into InnoDB quickly:
* use as large an InnoDB buffer cache as possible
* make the InnoDB log files as large as possible
* minimize the number of unique indexes on your tables
* disable all calls to fsync from InnoDB. You have to hack the code to
get this, or look at the Google patch. Of course, you only want to run
in this mode when loading the table.
MyISAM始终运行 在'nosync'模式下,也就是说,它永远不会调用fsync()来刷新文件 磁盘。
如果某些操作系统/计算机速度极慢,InnoDB的nosync非常有用 在fsync()中。但它不应该用在生产系统中。
同样的消息说,InnoDB有时使用另一种同步方法:
然后InnoDB使用fsync()来刷新数据和日志文件。如果O_DSYNC是 指定,InnoDB使用O_SYNC打开并刷新日志文件,但使用 fsync()来刷新数据文件。如果指定了O_DIRECT(某些可用) Linux版本从MySQL-4.0.14开始),InnoDB使用O_DIRECT打开 数据文件,并使用fsync()来刷新数据和日志文件。注意 InnoDB不使用fdatasync()或O_DSYNC,因为存在问题 与他们在许多Unix风格。
答案 2 :(得分:3)
请记住InnoDB处理密钥的方式可能会造成麻烦。由于所有内容都按照具有非自动增量主键的主键的顺序存储在磁盘上,因此可能导致大部分表在任何插入的磁盘上移动(当我有一个数据透视表并使用时,我遇到了这个问题)组合的id作为主键)。在磁盘上移动数据很慢。
InnoDB的索引大小也可以大得多,因为每个索引也包含主键。检查以确保没有遇到任何内存限制。
答案 3 :(得分:2)
首先,您的测试无效,因为当您具有并发性时,针对表级锁定的行级锁定的速度增益就会出现!只有1个螺纹制作插件,在这两种情况下,每个插件都有1个锁定/解锁,并且插入不会等待释放表级锁定。
秒,如JIStone所述,当表大小大于缓冲池时,非顺序主键是插入的性能杀手。
第三,缓冲池大小是InnoDB中最重要的设置之一。尽可能使它变得更长(建议的设置是可用RAM的80%)。
接下来,正如@wallyk所述,innodb_flush_log_at_trx_commit对I / O操作的速度起着至关重要的作用。
接下来,innodb_log_file_size和innodb_buffer_file_size非常重要。
接下来,请记住,由于您有2个唯一索引,因此在InnoDB可以插入行之前,它必须检查索引中是否存在值,并且索引很大。
如果没有关于表和索引的详细信息,我不能给你更多的建议,但请记住,没有存储引擎是灵丹妙药,虽然通常只需更改存储引擎就可以获得很快的速度,但是索引,或调整一个变量,在大规模系统中,事情比这更复杂。但是,正如我所说,你不应该在隔离测试中比较原始插入速度,你必须使测试尽可能接近真实应用。
更新:还有一个提示 在MyISAM和InnoDB中,多插入(插入....值(...),(...),(...))更快。此外,在InnoDB中,您可以在事务中进行插入,这会在事务完成之前禁用更新非唯一索引,并且它也更快(但不执行大事务,因为这实际上会因为使用的隔离级别而减慢速度行版本工作的方式。)