Повысить производительность при импорте данных в MySQL?

#python #mysql #xml #django #json

#python #mysql #xml #django #json

Вопрос:

Я использую Django для создания веб-сайта с серверной частью MySQL (MyISAM).

Данные базы данных импортируются из нескольких XML-файлов, которые обрабатываются внешним скриптом и выводятся в виде JSON-файла. Всякий раз, когда новый файл JSON отличается от старого, мне нужно стереть старый MySQL-db и воссоздать его с помощью manage.py loaddata, (по крайней мере, это самый простой способ сделать это, я думаю, я мог бы проверить различия между файлами JSON и применить их к базе данных, но я нея не нашел хорошего решения для этого (я не очень хороший программист и не веб-разработчик)).

В любом случае, файл JSON составляет около 10 Мб и в конечном итоге составляет около 21 000 строк SQL (ожидается, что он не будет значительно увеличиваться). Есть 7 таблиц, и все они выглядят примерно так:

 class Subnetwork(models.Model):
   SubNetwork = models.CharField(max_length=50)
   NetworkElement = models.CharField(max_length=50)
   subNetworkId = models.IntegerField()
   longName = models.CharField(max_length=50)
   shortName = models.CharField(max_length=50)
   suffix = models.CharField(max_length=50)
  

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

Для чего это стоит, вот некоторые выходные данные профилировщика https://gist.github.com/1287847

Комментарии:

1. Убедитесь, что DEBUG=False в settings.py . У меня был файл размером 300 МБ для импорта, который обычно выполнялся в течение часа или около того и завершался сбоем. Я изменил DEBUG, и он начал запускаться через 30 минут и завершался. Что-то о ORM, использующем больше памяти для кэширования запросов при DEBUG=True …

2. Это сократило время загрузки на пару секунд. Думаю, хорошее начало, спасибо.

Ответ №1:

Есть несколько решений, таких же достойных, как и другие, но вот обходной путь, позволяющий свести к минимуму «время простоя» вашей системы без необходимости написания механизма синхронизации БД (что, вероятно, было бы лучшим решением в большинстве случаев).:

  • Создайте пользовательский settings_build.py файл, с from settings import * помощью которого выберите случайное имя для новой БД (возможно, с датой в имени БД), создайте его, вызвав mysqladmin, и обновите имя в DATABASES .
  • Создайте пользовательскую команду управления django (назовем ее builddb ), либо клонировав loaddata команду, либо вызвав ее, и при успешном результате она должна записать имя базы данных в dbname текстовый файл в одну строку и выполнить команду оболочки, которая перезагрузит ваш сервер django (apache / gunicorn /?).
  • Измените свой settings.py , чтобы загрузить имя базы данных из текстового файла.

А теперь запустите процесс сборки следующим образом:

 ./manage.py builddb --settings=settings_build
  

Комментарии:

1. Я думал об этом варианте (то есть о создании новой базы данных для каждого импорта), но, к сожалению, у меня нет полного доступа к MySQL-серверу, и я могу использовать только назначенную мне базу данных.

2. Если вы можете получить доступ к еще одной базе данных, вы все равно можете использовать этот метод, чередуя две базы данных.

3. Верно. Я мог бы использовать это в качестве последнего средства, если я не придумаю способ реально сократить время.

Ответ №2:

Я решил это, экспортировав обработанные XML-файлы в csv вместо json, а затем использовал отдельный скрипт, который вызывал mysqlimport для выполнения импорта.