MySQL INSERT на большой стол - могу ли я улучшить быстродействие?

0

У меня есть таблица MyISAM с двумя полями f1 и f2, как целыми, так и незанятыми, и не может быть нулевым. Таблица преднамеренно не имеет первичного ключа, но имеет индекс на f2. В таблице в настоящее время содержится 320 миллионов строк.

Я хотел бы иметь возможность вставлять новые строки (около 4000 раз в неделю) в эту таблицу с приличной скоростью. Однако в настоящее время я вставляю около 4000 строк за 2 минуты. (Я делаю это, используя текстовый файл и команду "source" - текстовый файл содержит только инструкции INSERT в этой таблице). Есть ли способ ускорить высказывания вставки? Кроме того, во время выполнения инструкций INSERT будут ли затронуты или замещены какие-либо операторы SELECT/JOIN в одну и ту же таблицу?

  • 0
    Идея: MySQL 5.1 добавил разделение таблиц
Теги:
performance
insert

4 ответа

3

Вы можете разгружать инструкции вставки из

INSERT INTO table (f1, f2) VALUES ($f1, $f2);
INSERT INTO table (f1, f2) VALUES ($other, $other);
etc...

в

INSERT INTO table (f1, f2) VALUES ($f1, $f2), ($other, $other), etc...

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

4000 строк за 2 минуты все еще 33 строки в секунду. Это не слишком потрепанный, особенно на огромной таблице, где индекс должен быть обновлен. Вы можете отключить ключи в таблице перед выполнением вставки, а затем снова восстановить ключ с помощью REPAIR TABLE, но это может занять больше времени, особенно с 320 миллионами строк для сканирования. Вам нужно будет провести бенчмаркинг, чтобы убедиться, что это достойно.

Что касается SELECTS/JOINS, так как вы находитесь на таблицах MYISAM, нет способа скрыть новые таблицы в транзакции, пока они не будут выполнены. Каждая строка сразу будет видна для другого сеанса по мере его ввода, если вы не заблокируете таблицу, чтобы получить эксклюзивный доступ к ней для вставок. Но тогда вы заблокировали всех остальных во время работы вставки.

  • 0
    2 других подхода включают загрузку ваших данных в новую временную таблицу и вставку их в основную таблицу с помощью вставки в таблицу select * from temp; или массовая загрузка их с LOAD DATA INFILE
0

@rjk корректно. LOAD DATA INFILE - это самый быстрый способ получить данные в вашей таблице. Мало других мыслей.

Мне кажется, 2 минуты для строк 4k. SELECT блокируют INSERT в MyISAM и, вероятно, замедляют ваши вставки. Я настоятельно рекомендую InnoDB, у которого нет этой проблемы, плюс лучшее восстановление после сбоя и т.д. Если вы должны использовать MyISAM, блокировка таблицы перед запуском ваших вставок может помочь или вы можете попробовать INSERT DELAYED, которая позволит операциям INSERT немедленно возвращаться и быть обрабатывается, когда таблица свободна.

  • 0
    Привет, спасибо за ваш комментарий. Я не хотел бы использовать InnoDB, так как моя система состоит в основном из запросов SELECT, и мне нужно выполнять INSERT только один раз в неделю, в течение которых система будет отключена, чтобы не было одновременных выборок. Я использовал LOAD DATA INFILE, но включение ключей (после отключения) занимает много времени. Я хотел бы попытаться оптимизировать повторное включение этого ключа. Спасибо
0

Если для загрузки данных можно получить доступ к базе данных, вы можете использовать команду LOAD DATA INFILE. Как описано в руководстве:

Оператор LOAD DATA INFILE читает строки из текстового файла в таблицу на очень высокая скорость.

Надеюсь, что это поможет.

  • 0
    Спасибо, я использовал LOAD DATA INFILE. Мне нужно будет вставить до 200 000 строк, и это по-прежнему занимает много времени с включенными индексами. Поэтому я попытался ИЗМЕНИТЬ ТАБЛИЦУ ... ОТКЛЮЧИТЬ КЛЮЧИ, ... ЗАГРУЗИТЬ ДАННЫЕ ИНФИЛЯ ... ИЗМЕНИТЬ ТАБЛИЦУ ... ВКЛЮЧИТЬ КЛЮЧИ. Однако включение ключей для 320 миллионов строк занимает много времени. Я подумал, может ли быть какая-то ценность в файле .cnf, чтобы сделать это быстрее?
0

Насколько я знаю, команда source - это самый быстрый способ сделать это. Поскольку таблица MyISAM, вся таблица блокируется во время действий записи. Поэтому да, все SELECT -statements помещаются в очередь до тех пор, пока все вставки/обновления/удаления не закончатся.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню