MySQL LOAD DATA INFILE замедляется после начальной вставки, используя raw sql в django - PullRequest
0 голосов
/ 21 марта 2011

Я использую следующий пользовательский обработчик для выполнения массовой вставки с использованием raw sql в django с бэкэндом MySQLdb с таблицами innodb:

def handle_ttam_file_for(f, subject_pi):
    import datetime
    write_start = datetime.datetime.now()

    print "write to disk start: ", write_start
    destination = open('temp.ttam', 'wb+')
    for chunk in f.chunks():
        destination.write(chunk)
    destination.close()
    print "write to disk end", (datetime.datetime.now() - write_start)

    subject = Subject.objects.get(id=subject_pi)

    def my_custom_sql():
        from django.db import connection, transaction
        cursor = connection.cursor()

        statement = "DELETE FROM ttam_genotypeentry WHERE subject_id=%i;" % subject.pk
        del_start = datetime.datetime.now()
        print "delete start: ", del_start
        cursor.execute(statement)
        print "delete end", (datetime.datetime.now() - del_start)

        statement = "LOAD DATA LOCAL INFILE 'temp.ttam' INTO TABLE ttam_genotypeentry IGNORE 15 LINES (snp_id, @dummy1, @dummy2, genotype) SET subject_id=%i;" % subject.pk

        ins_start = datetime.datetime.now()
        print "insert start: ", ins_start
        cursor.execute(statement)
        print "insert end", (datetime.datetime.now() - ins_start)
        transaction.commit_unless_managed()

    my_custom_sql()

Загруженный файл имеет 500k строк и имеет размер ~ 15M.

По мере добавления файлов время загрузки постепенно увеличивается.

Insert times:
1st:    30m
2nd:    50m
3rd:    1h20m
4th:    1h30m
5th:    1h35m

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

1 Ответ

0 голосов
/ 21 марта 2011

Я обнаружил, что основной проблемой при массовой вставке в мою таблицу innodb была настройка mysql innodb, которую я пропустил.

Настройка для innodb_buffer_pool_size по умолчанию составляет 8M для моей версии mysql и вызывает значительное замедление по мере увеличения размера таблицы.

innodb-performance-optimization-basics

choosing-innodb_buffer_pool_size

Рекомендуемый размер в соответствии со статьями составляет 70-80 процентов памяти при использовании выделенного сервера mysql. После увеличения размера пула буферов мои вставки сократились с часа + до менее 10 минут без каких-либо других изменений.

Еще одним изменением, которое я смог сделать, стало использование аргумента LOCAL в операторе LOAD DATA (спасибо @ f00). Раньше моя проблема заключалась в том, что я продолжал получать файл не найден или не мог получить статистические ошибки при попытке получить доступ к файлу mysql, загруженному django.

Оказывается, это связано с использованием Ubuntu и этой ошибкой .

  1. Выберите каталог, из которого mysqld должно быть разрешено загружать файлы. Возможно, где-то только для записи Ваша учетная запись DBA и доступна только для чтения члены группы mysql?

  2. sudo aa-complain / usr / sbin / mysqld

  3. Попробуйте загрузить файл из указанного вами каталога загрузки: 'load данные '/var/opt/mysql-load/import.csv' в стол ... '

  4. sudo aa-logprof aa-logprof определит нарушение прав доступа запускается загрузкой данных ... 'и интерактивно проведет вас через разрешение доступа в будущем. Вы, вероятно, хотите выбрать Glob из меню, так что вы в конечном итоге читать доступ к '/ var / opt / mysql-load / *'. Как только вы выбрали правильное (глобус), выберите Разрешить из меню, чтобы закончить. (N.B. Do не включить хранилище при появлении запроса сделайте это при первом запуске аа-логпроф, если вы действительно понять всю одежду процесс.)

  5. sudo aa-forcece / usr / sbin / mysqld

  6. Попробуйте снова загрузить файл. Это должно сработать на этот раз.

...