Я вижу везде, где программисты обсуждают оптимизацию для самых быстрых LOAD DATA INFILE вставок. Но они никогда не объясняют многое своим выбором значений и т. Д., И оптимизация зависит от среды, а также от реальных реальных потребностей.

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

Мой конфиг, двухъядерный процессор Intel с тактовой частотой 3,30 ГГц, 4 ГБ оперативной памяти DDR4 (Windows7 сообщает «2,16 ГБ доступно» из-за зарезервированной памяти).

Мой файл backup.csv имеет открытый текст и составляет около 5 миллиардов записей, поэтому он имеет огромный размер файла 500 Гб, такой как эта схема (но длина шестнадцатеричной строки 64):

 "sdlfkjdlfkjslfjsdlfkjslrtrtykdjf";"dlksfjdrtyrylkfjlskjfssdlkfjslsdkjf"

В моей таблице только два поля, и первое - Уникальный индекс. ROW-FORMAT установлен на FIXED для экономии места. По той же причине тип поля установлен как BINARY (32).

Я использую движок MyISAM. (потому что innoDB требует гораздо больше места!) (MySQL версия 5.1.41)

Вот код, который я планировал использовать сейчас:

 ALTER TABLE verification DISABLE KEYS;
 LOCK TABLES verification WRITE;
 LOAD DATA INFILE 'G:\\backup.csv'
      IGNORE INTO TABLE verification
      FIELDS TERMINATED BY ';' ENCLOSED BY '"' LINES TERMINATED BY '\r\n'
      (@myhash, @myverif) SET hash = UNHEX(@myhash), verif = UNHEX(@myverif);
 UNLOCK TABLES;
 ALTER TABLE verification ENABLE KEYS;

Как вы можете видеть, команда use LOAD DATA INFILE принимает значения в виде простого текста, превращая их в HEX (оба окончательно шестнадцатеричные хеши, так что ...)

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

Я также прочитал на документацию:

 myisamchk --keys-used=0 -rq /var/lib/mysql/dbName/tblName

Выполнение этого перед вставкой также ускорит его. Но что на самом деле tblName? (потому что у меня есть файл .frm, .MYD и .MYI, на какой из них я должен указывать?)

Вот последние короткие подсказки, которые я читал об оптимизации

РЕДАКТИРОВАТЬ: Забыл сказать, все это localhost.

1
user3916429 29 Май 2017 в 02:21

2 ответа

Лучший ответ

Итак, мне наконец-то удалось вставить свою базу данных объемом 500 ГБ, содержащую более 3 миллиардов записей, примерно за 5 часов.

Я перепробовал много способов, и при восстановлении Primary Index я застрял с этой ошибкой ERROR 1034 (HY000): Duplicate key 1 for record at 2229897540 against new record at 533925080.

Сейчас я объясню, как мне удалось завершить вставку:

  • Я отсортировал мой .csv файл с помощью GNU CoreUtils : sort.exe (я на Windows), имейте в виду, что для временных файлов вам нужно в 1,5 раза больше файла csv в качестве свободного места. (так что, считая файл .csv, он в 2,5 раза меньше)
  • Вы создаете таблицу, с индексами и все.
  • Выполнить mysqladmin flush-tables -u a_db_user -p
  • Выполнить myisamchk --keys-used=0 -rq /var/lib/mysql/dbName/tblName
  • Вставьте данные: (НЕ ИСПОЛЬЗУЙТЕ ALTER TABLE tblname DISABLE KEYS; !!!)

    LOCK TABLES verification WRITE;
    LOAD DATA INFILE 'G:\\backup.csv'
        IGNORE INTO TABLE verification
        FIELDS TERMINATED BY ';'
        ENCLOSED BY '"'
        LINES TERMINATED BY '\r\n'
        (@myhash, @myverif) SET hash = UNHEX(@myhash), verif = UNHEX(@myverif);
    UNLOCK TABLES;
  • когда данные вставлены, вы перестраиваете индексы, выполнив myisamchk --key_buffer_size=1024M --sort_buffer_size=1024M -rqq /var/lib/mysql/dbName/tblName (обратите внимание, что -rqq, удвоение q будет игнорировать возможную повторяющуюся ошибку, пытаясь исправить ее (вместо того, чтобы просто останавливать вставки после многих часов ожидания!)

  • Выполнить mysqladmin flush-tables -u a_db_user -p

И я был сделан!

  • Я заметил значительное увеличение скорости, если файл .csv находится на другом диске, чем база данных, и то же самое для операции sort, поместите временный файл на другой диск. (Скорость чтения / записи не совпадает с данными в одном и том же месте)

Источник этого снова был здесь: Авторские права на это решение

1
user3916429 19 Июн 2017 в 17:38

Я почти уверен, что это проверка, а не verification.MYD или два других. .MYD - данные, .MYI - индексы, .frm - схема.

Как долго эти строки? Есть гекс? Если 32 шестнадцатеричных числа, то вы не хотите BINARY(16) для вывода UNHEX?

Длинная часть процесса, вероятно, будет ENABLE KEYS, когда именно он будет создавать индекс. Делайте SHOW PROCESSLIST;, пока он работает - если он говорит «с помощью буфера ключей», убейте его, это будет длиться вечно. Если это говорит что-то вроде «строительство по ремонту», то, что это хорошо - это сортировка, то загрузка индекса эффективно.

Вы можете сэкономить 5 ГБ дискового пространства, установив myisam_data_pointer_size=5 перед началом процесса. Похоже, что есть также myisam_index_pointer_size, но по умолчанию оно может быть равно 5, что, вероятно, правильно для вашего случая. (Я встречался с этим параметром один раз на версии 4.0 примерно в 2004 году; но никогда больше.)

Я не думаю, что key_buffer_size будет иметь значение во время загрузки и индексирования - поскольку вы действительно хотите, чтобы он не использовал key_buffer. Не устанавливайте его так высоко, чтобы у вас не хватило оперативной памяти. Обмен ужасен для производительности.

1
Rick James 29 Май 2017 в 04:18