【问题标题】:MySQL Insert Performance stressToolMySQL 插入性能压力工具
【发布时间】:2012-02-09 19:25:14
【问题描述】:

*如果你懒得看描述,你可以在最后找到我的问题......

你好,我建立了一个简单的数据库:

CREATE TABLE `users` (
  `id` varchar(45) NOT NULL,
  `full_name` varchar(45) NOT NULL,
  `first_name` varchar(45) NOT NULL,
  `last_nmae` varchar(45) NOT NULL,
  `login` varchar(45) NOT NULL,
  `password` varchar(45) NOT NULL,
  PRIMARY KEY (`id`,`full_name`,`login`),
  UNIQUE KEY `idusers_UNIQUE` (`id`),
  UNIQUE KEY `login_UNIQUE` (`login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$

现在我正在测试插入单行的性能。

我用 C# 创建了一个压力工具并将其运行到 1M 行。 如果您有兴趣,这是代码:

abstract class Job
    {
        private static object synObject = new object();
        private static int _id = 0;
        private static DateTime startingTime = DateTime.Now;
        private const int JOB_PER_SIRCLE = 10;

        protected int id;
        public Job()
        {
            lock (synObject)
            {
                _id++;
                id = _id;
            }
        }

        public void run()
        {
            while (true)
            {
                for (int i = 0; i < JOB_PER_SIRCLE; i++)
                {
                    doJob();
                }
                lock (synObject)
                {
                    calculate();
                }
            }
        }

        private static DateTime lastLog = DateTime.Now;
        private static long numOfJobsAcomplished = 0;
        private static long totalNumOfJobsAcomplished = 0;

        private static void calculate()
        {
            totalNumOfJobsAcomplished += JOB_PER_SIRCLE;
            numOfJobsAcomplished += JOB_PER_SIRCLE;
            DateTime now = DateTime.Now;
            TimeSpan timePass = now - lastLog;

            if (timePass.TotalSeconds > 1)
            {
                double total = 1000000;
                TimeSpan speed = TimeSpan.FromMilliseconds(timePass.TotalMilliseconds / numOfJobsAcomplished * total);
                Console.WriteLine("Speed = " + String.Format("{0:00.0000}", speed.TotalMinutes) + " Completed " + String.Format("{0:00.000}", totalNumOfJobsAcomplished / total * 100) + "% time pass " + (now - startingTime));
                lastLog = now;
                numOfJobsAcomplished = 0;
            }
        }

        protected abstract void doJob();
    }

在 doJob() 方法中,我正在执行插入操作,我正在运行 16 个作业,16 个线程(我发现这是我机器上的最佳性能)

无论如何,我的问题是关于结果的,我需要 85 到 105 分钟来插入 1,000,000 行。这是快还是我应该寻找不同的数据库来使用?

附言 * 当我插入时,我还使用 MD5Crypt 算法进行散列

【问题讨论】:

  • Is this fast 是主观的。您的要求和/或限制是什么?负载行为在现实中会是什么样子?表上还会发生哪些其他读取或写入活动?此外,SQL 查询的格式也很重要。您是否使用参数化查询来最小化网络流量、解析和编译时间等?
  • @Dems 我只是在使用“插入用户值('...');”
  • 查看参数化查询。如果您一次又一次地重复相同的查询,它们的执行速度通常会更快。
  • @Dems 但不是同一个查询,参数在变化
  • 某事告诉我Console.WriteLine 花费了大量时间。

标签: mysql sql performance stress-testing


【解决方案1】:

如果您想优化插入性能,我建议您将主键更改为合成自动增量 bigint。原因是 Innodb 在主键上使用聚集索引,它按范围存储键。如果您使用非顺序主键,则需要读取一个内存块并在最坏的情况下为每一行写回它,而不是像使用顺序键那样使用缓存。当您插入顺序键时,性能会提高几个数量级,请尝试一下。

CREATE TABLE `users` (
  `id` bigint(20) auto increment not null PRIMARY KEY,
  `user_id` varchar(45) NOT NULL,
  `full_name` varchar(45) NOT NULL,
  `first_name` varchar(45) NOT NULL,
  `last_nmae` varchar(45) NOT NULL,
  `login` varchar(45) NOT NULL,
  `password` varchar(45) NOT NULL,
  UNIQUE KEY (`user_id`,`full_name`,`login`),
  UNIQUE KEY `idusers_UNIQUE` (`user_id`),
  UNIQUE KEY `login_UNIQUE` (`login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$

顺便说一句,我不确定之前的 id(user_id) 是什么,所以我留下了,但如果你把它用作合成主键,你可以把它拿出来。

【讨论】:

  • 好的,我运行一个测试,看起来对性能没有影响
  • 你尝试了多少行?您还想确保您的 innodb_buffer_size 设置正确,现在设置为什么?
  • 我的意思是innodb_buffer_pool_size,你可以通过运行`show variables like 'innodb_buffer_pool_size'来获取值;或通过查看您的 my.cnf 文件
【解决方案2】:

当有人试图“责备”软件的写入速度而不考虑其他因素时,我总是觉得很有趣。那么,让我们开始吧。

MySQL 有 2 个广泛使用的引擎。 MyISAM 和 InnoDB。 InnoDB 是一个事务引擎,它使用集群主键将记录写入硬盘。 这意味着它会进行各种计算,以便将数据安全地写入磁盘并让顺序记录彼此相邻写入。 这意味着使用主键查找速度很快,但需要一段时间才能写下来。

将其翻译成简单的英语,这意味着您的计算机将更加努力地将数据物理写入磁盘安全,并且它可以快速找到记录。

这也意味着整个考验的瓶颈是你的硬盘。 85 分钟插入 1 百万。记录大约是每秒 200 次插入。对于常规的 7200 RPM 机械驱动器来说,这是一个相当不错的数字(我的驱动器可以达到 350ish IOPS)。因此,在 350 IOPS(让我们拿我的驱动器)中,您达到了 200,这是一个很好的数字,因为您的 HDD 用于读取和写入,并且您的操作系统可能运行了几个需要 HDD I/O 的服务。

TL;DR - 如果您使用不同的软件,开始时的写入速度会稍快一些。在更换软件之前,您需要考虑所有因素。

【讨论】:

  • 我没有说我在责怪 MySQL。我只是想了解这是否是一个很好的速度。当我启动我的服务器时,很多事情都会运行。我只是想创建一个性能好的平面。
  • 我试图证明插入速度很大程度上取决于硬件,尤其是在 HDD 子系统上。基本上是的,对于机械 7200 RPM 硬盘来说,它的速度还可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-08
  • 2011-03-24
  • 2010-10-05
  • 1970-01-01
  • 2016-12-10
相关资源
最近更新 更多