繁体   English   中英

InnoDB 与 MyISAM 插入查询时间

[英]InnoDB vs. MyISAM insert query time

我有一个大型 MySQL 表(约 1000 万行,6.5G),用于读写。 它是 MyISAM,由于 MyISAM 的所有表在写入时锁定,我得到了很多锁定。

我决定尝试迁移到推荐用于读/写表的 InnoDB,它只在写入时锁定特定行。

转换后,我测试了插入语句,结果发现 InnoDB 表中的时间比 MyISAM 表中的时间多约 15 倍(从 0.1 秒到 1.5 秒)。 这是为什么?

我还没有为 InnoDB 配置任何东西,也计划添加分区,但是这个数字对我来说仍然是出乎意料的。 当然,表是相同的,相同的索引等。

根据要求提供的附加信息:

2个指标。 主要是 Big INT 类型的 data_id 和 varchar(255) 类型的非唯一 user_id。

插入大约有 150 行,它们具有相同的 user_id。

索引大小:MyISAM 200 MB,InnoDB 400MB

一个相关的答案表明,当写入与读取的比率相对较高时,将innodb_flush_log_at_trx_commit变量设置为 2 可能会提高性能。 有关更多信息,请参阅文档

我认为,InnoDB 实现了真正的 ACID,并且做了很多fsync()来保存数据。 而且 MyISAM 不是真正的 ACID,并且 fsync() 的作用更少。

当您需要加载大量数据时, 有一些建议可以杀死 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(在一些从 MySQL-4.0.14 开始的 Linux 版本上可用),InnoDB 使用 O_DIRECT 打开数据文件,并使用 fsync() 刷新数据和日志文件。 请注意,InnoDB 不使用 fdatasync() 或 O_DSYNC,因为它们在许多 Unix 版本上都存在问题。

请记住 InnoDB 处理键的方式可能会导致麻烦。 由于所有内容都按照具有非自动增量主键的主键的顺序存储在磁盘上,因此可能会导致大部分表随任何插入移动到磁盘上(当我有一个数据透视表并使用组合的 id 作为主键)。 在磁盘上移动数据很慢。

此外,InnoDB 的索引大小可以更大,因为每个索引还包含主键。 检查以确保您没有遇到任何内存限制。

首先,你的测试是无效的,因为当你有并发时,行级锁定相对于表级锁定的速度增益来了! 只有 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 中,多插入(插入 .... values(...),(...),(...))更快。 此外,在 InnoDB 中,您可以在事务中进行插入,这会在事务完成之前禁用更新非唯一索引,而且速度也更快(但不要执行大型事务,因为这实际上会因为使用的隔离级别而减慢速度和行版本控制的工作方式)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM