【问题标题】:MySQL InnoDB insert performance (Windows)MySQL InnoDB 插入性能 (Windows)
【发布时间】:2011-05-05 10:24:11
【问题描述】:

我是 MySQL 新手,我对 InnoDB 性能有些怀疑。我有一张表,我想在其中存储一些度量值,并且我正在使用存储过程中的循环测试密集插入:

CREATE TABLE `measures` (
  `Id` int(10) unsigned NOT NULL,
  `DT` datetime NOT NULL,
  `TF1` float DEFAULT '0',
  `IF1` float DEFAULT '0',
  `PAF1` float DEFAULT '0',
  `PRF1` float DEFAULT '0',
  `CF1` float DEFAULT '0',
  `TF2` float DEFAULT '0',
  `IF2` float DEFAULT '0',
  `PAF2` float DEFAULT '0',
  `PRF2` float DEFAULT '0',
  `CF2` float DEFAULT '0',
  `TF3` float DEFAULT '0',
  `IF3` float DEFAULT '0',
  `PAF3` float DEFAULT '0',
  `PRF3` float DEFAULT '0',
  `CF3` float DEFAULT '0',
  `CTotal` float DEFAULT '0',
  PRIMARY KEY (`Id`,`DT`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE PROCEDURE `sp_INSERT_TEST`()
BEGIN
        DECLARE i INT DEFAULT 1;

        WHILE (i<=6000) DO

            INSERT INTO measures
            (Id, DT, TF1, IF1, PAF1, PRF1, CF1, TF2, IF2, PAF2, PRF2, CF2, 
TF3, IF3, PAF3, PRF3, CF3, CTotal) 
            VALUES 
            (1, TIMESTAMPADD(MINUTE,i, NOW()), 
            0.1, 1, 10, 100, 1000,
            0.2, 2, 20, 200, 2000,
            0.3, 3, 30, 300, 3000,
            i * 10);

            SET i=i+1;
        END WHILE;
END

执行的总时间约为150秒,但如果我使用MyISAM而不是InnoDB,时间约为0.2秒。

两个引擎之间的这种性能差异是否正常?是否可以使用 InnoDB 改进插入以接近 MyISAM 性能还是引擎限制?

注意:我使用的是 MySQL 5.1.56(64 位)Windows 7 x64,默认配置为开发人员机器(我也尝试过服务器配置但性能相似)。

提前致谢。 约翰

【问题讨论】:

    标签: mysql windows performance innodb


    【解决方案1】:

    就像 peufeu 所说,您只需使用一个事务就可以大大提高性能。如果您愿意放松 ACID,您可以通过设置获得更好的性能

    innodb_flush_log_at_trx_commit=0
    

    在我的.ini 中。

    【讨论】:

      【解决方案2】:

      是的,这很正常。像所有事务数据库一样,InnoDB 必须确保 ACID 一致性,这需要大量工作,而且会影响您的性能的是,在每个事务结束时,它必须等待硬盘说“OK,数据已写入”,至于 ACID 中的“D=Durability”。

      解决方案只是在单个事务中发出批量 INSERT,即 BEGIN、mass INSERT、COMMIT。

      或者使用更适合的东西,比如 LOAD DATA INFILE,或者至少使用多行 INSERT。

      【讨论】:

        【解决方案3】:

        InnoDB 通常比 MyISAM 慢,它是一个具有ACID 属性的事务数据库引擎。但是,更改配置或做事方式可能会对速度产生很大影响。

        首先一些不起作用的东西:添加缓存是无用的,减少表上的索引数量会有所帮助,因为您在插入时必须创建更少的索引,但在您的情况下,您只有主键。

        我的建议是尝试以下方法之一:

        • 在单个事务中运行所有 INSERT 查询,然后在最后提交。

          示例:SET 自动提交=0; 插入语句; 提交;

        • 使用扩展的插入语法,允许一起插入多行。我认为 InnoDB 不支持,但我只是尝试使用 MySQL 5.0.75 并且它有效。我不认为你可以一次插入所有 6000 行,因为你受到 max_allowed_pa​​cket 的限制(如果你愿意,你可以增加它)。例如,您可以一次插入 500 行。

          示例:INSERT INTO 表 (field1, field2) 价值观 (1, 测试'), (2, '你好');

        【讨论】:

        • 使用扩展的插入语法使得 mysql 在一个事务中进行多次插入,即使自动提交关闭。所以是的,这是个好主意。
        • 我不同意您的第一句话“Innodb 性能很差”。没有开源引擎支持其竞争通用工作的功能集,所以我认为你可能错了。
        • @MarkR 我并不是要抨击 InnoDB,也许我可以将其改写为“比 MyISAM 慢得多”。至于替代品,PostgreSQL 呢?
        • 是的,Postgresql 是一个更公平的比较,MyISAM 没有持久性(甚至无法配置为具有任何持久性),并发性有限且从错误中恢复很差。
        • 我把我的第一句话改写了一点,对InnoDB没有必要苛刻,我个人也使用它。
        【解决方案4】:

        其他海报是正确的 - 一次性完成所有工作。

        6000 行是一个如此小的表,插入性能与如此小的数据集并不真正相关。

        无论如何,现代数据库都没有针对这种“玩具”系统进行优化。

        尝试 10 亿条记录,并通过合理的交易规模来实现,然后看看谁会胜出。

        拔掉插头,看看谁恢复得更快(提示:不会是myisam)

        使用 LOAD DATA INFILE 或批量插入可能会提供更好的存储过程性能,即使它在一个事务中,因为 mysql SP 语言并不总是特别有效。

        【讨论】:

          【解决方案5】:

          除了 stivlo 所说的一切 - 您可能会发现以下文章和随附的视频很有用。

          http://www.mysqlperformanceblog.com/2011/03/18/video-the-innodb-storage-engine-for-mysql/

          正如 Morgan Tocker 在他的演讲中所说的“朋友不要让朋友使用 myisam”

          希望你觉得它很有启发性:)

          【讨论】:

            【解决方案6】:

            在插入方面,MyISAM 比 InnoDB 快,但差距不到 750 倍,这表明您需要对 InnoDB 进行调整。 这是一个之前已经介绍过的主题,例如您可以在following blog阅读一些好东西。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-08-01
              • 2018-07-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-08-04
              • 2016-12-10
              • 2016-03-19
              相关资源
              最近更新 更多