Оптимизация производительности таблицы MySql - хэш как первичный ключ или уникальный ключ - PullRequest
0 голосов
/ 11 сентября 2018

Обновление *: Посмотрев на мой скрипт на Python, я обнаружил, что подготовка и вычисление данных перед вставкой записей - это самое большое время обработки, а не вставка в БД. Вставки на самом деле относительно быстрые (около 30 секунд для 10 000 записей с размером таблицы 1 000 000 записей). Однако я думаю, что отзывы, которые я получил по этому вопросу, также помогут мне оптимизировать вставки. Спасибо всем, кто ответил. Теперь я собираюсь попытаться оптимизировать мой скрипт на Python, чтобы ускорить его.

В настоящее время у меня есть таблица MariaDB со следующей структурой:

CREATE TABLE IF NOT EXISTS `adeck_errors` (
  `StormID` varchar(8) NOT NULL DEFAULT '1',
  `ModelBaseTime` datetime NOT NULL,
  `Model` varchar(4) NOT NULL,
  `Tau` smallint(4) NOT NULL,
  `LatCARQ` float DEFAULT NULL,
  `LonCARQ` float DEFAULT NULL,
  `LatModel` float DEFAULT NULL,
  `LonModel` float DEFAULT NULL,
  `DistError` smallint(6) DEFAULT NULL,
  `WindCARQ` int(11) DEFAULT NULL,
  `WindModel` int(11) DEFAULT NULL,
  `WindError` smallint(6) DEFAULT NULL,
  `PresCARQ` int(11) DEFAULT NULL,
  `PresModel` int(11) DEFAULT NULL,
  `PresError` smallint(6) DEFAULT NULL,
  UNIQUE KEY `StormID` (`StormID`,`ModelBaseTime`,`Model`,`Tau`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Как вы можете видеть, мой уникальный ключ находится в четырех полях таблицы, чтобы я не получил повторяющихся записей. Когда я вставляю более 10 000 записей в таблицу, которая уже содержит 1 миллион записей, это занимает около 15-20 минут, и я хотел бы ускорить этот процесс.

Мой вопрос: лучше ли было бы создать хэш данных в 4 полях и использовать этот хэш в качестве первичного ключа, чтобы у меня не было дубликатов? Когда я обрабатываю данные перед вставкой (с помощью Python), я могу быстро создать хеш-значение из 4 фрагментов данных, прежде чем перейти к функции вставки в БД.

Спасибо за ваши предложения. Bryan

Ответы [ 2 ]

0 голосов
/ 03 октября 2018
  • Измените ключ UNIQUE на PRIMARY. Это, вероятно, не окажет никакого влияния, однако сделает ваши намерения более ясными.
  • дедупликация должна работать нормально.
  • Для повышения производительности сортируйте входящие данные по PK перед началом загрузки.
  • Как вы грузите? Если вы получаете данные в CSV-файле, LOAD DATA лучше, многострочный INSERTs - второй; один ряд за раз медленнее.
  • UUID был бы очень плох для производительности; не делай этого.
  • innodb_buffer_pool_size должно составлять около 70% доступной оперативной памяти.
0 голосов
/ 11 сентября 2018

В настоящее время у вас нет «правильного» или «нормального» первичного ключа.Это актуально, потому что первичный ключ используется в качестве так называемого кластеризованного индекса для упорядочивания строк на диске.InnoDB выберет следующий подходящий ключ в качестве кандидата для кластеризованного индекса:

  • Если вы не определите PRIMARY KEY для своей таблицы, MySQL найдет первый индекс UNIQUE, где всеключевые столбцы - NOT NULL, и InnoDB использует его в качестве кластеризованного индекса.

В вашем случае это единственный существующий уникальный ключ "StormId".Ваши строки сортируются на диске по этому ключу, и теперь у вас возникает та же проблема, что и при использовании GUID / UUID в качестве первичного ключа.Когда вы читаете такие вопросы и статьи, как Различия между int и uuid в mysql , http://kccoder.com/mysql/uuid-vs-int-insert-performance/ или https://www.percona.com/blog/2007/03/13/to-uuid-or-not-to-uuid/, вы видите, что не следует использовать такой ключ для сортировки строкдиск.

Создайте обычный столбец BIGINT AUTO_INCREMENT PRIMARY KEY, чтобы повысить производительность.

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