MySQL Вставить Производительность StressTool - PullRequest
1 голос
/ 13 января 2012

* Если вам лень читать описание, в конце концов вы найдете мой вопрос ...

Привет, я строю простую базу данных:

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 Job, 16 потоков (я обнаружил, что это лучшая производительность на моей машине)

В любом случае, мой вопрос о результате, у меня есть от 85 до 105 минут, чтобы вставить 1 000 000 строк. Это быстро или мне нужно искать другую базу данных для работы?

P.S * Когда я вставляю, я также хэширую с алгоритмом MD5Crypt

Ответы [ 2 ]

1 голос
/ 13 января 2012

Мне всегда смешно, когда кто-то пытается «обвинить» скорость записи в программном обеспечении без учета других факторов. Итак, начнем.

MySQL имеет 2 широко используемых движка. MyISAM и InnoDB. InnoDB - это транзакционный механизм, который использует кластерный первичный ключ для записи записей на жесткий диск. Это означает, что он выполняет все виды вычислений, чтобы безопасно записывать данные на диск и иметь последовательные записи, записанные рядом друг с другом. Это означает, что поиск по первичному ключу выполняется быстро, но для записи требуется некоторое время.

Чтобы перевести это на простой английский, это означает, что ваш компьютер будет работать немного тяжелее, чтобы физически безопасно записать данные на диск и таким образом, чтобы он мог быстро находить записи.

Это также означает, что узким местом во всем этом тяжелом испытании является ваш жесткий диск. 85 минут, чтобы вставить 1 мил. записей примерно 200 вставок в секунду. Это довольно хорошая цифра для обычного механического привода 7200 об / мин (мой привод может достигать 350ish IOPS). Таким образом, из 350 операций ввода-вывода в секунду (давайте возьмем мой диск) вы получили 200, что является отличным показателем, когда ваш жесткий диск используется для чтения и записи, и у вас, вероятно, есть несколько служб, работающих в вашей ОС, требующих ввода-вывода жесткого диска.

TL; DR - если вы используете другое программное обеспечение, запись может быть немного быстрее при запуске. Перед заменой программного обеспечения необходимо принять во внимание все факторы.

0 голосов
/ 14 января 2012

Если вы хотите оптимизировать производительность вставки, могу ли я предложить вам изменить ваш первичный ключ на синтетическое автоматическое увеличение 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) был раньше, поэтому я ушел, но вы могли бы его убрать, если использовали его в качестве синтетического первичного ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...