在使用django中的原始sql进行初始插入后,MySQL LOAD DATA INFILE会变慢

时间:2011-03-20 23:41:13

标签: mysql django load-data-infile

我正在使用以下自定义处理程序在django中使用原始sql进行批量插入,并使用带有innodb表的MySQLdb后端:

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 :(得分:0)

我发现批量插入我的innodb表的主要问题是我忽略的mysql innodb设置。

对于我的mysql版本,innodb_buffer_pool_size的设置默认为8M,并且随着我的表格大小的增长导致速度大幅下降。

innodb-performance-optimization-basics

choosing-innodb_buffer_pool_size

如果使用专用的mysql服务器,根据文章推荐的大小是内存的70%到80%。增加缓冲池大小后,我的插入时间从一小时+到不到10分钟,没有其他更改。

我能够做的另一个改变是在LOAD DATA语句中获取LOCAL参数(感谢@ f00)。我之前的问题是,我一直在找不到文件,或者在尝试让mysql访问django上传的文件时无法获取stat错误。

事实证明这与使用ubuntu和bug

有关
  
      
  1. 选择一个允许mysqld加载文件的目录。   也许某处只能写作   您的DBA帐户,只能通过   组mysql的成员?

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

  4.   
  5. 尝试从指定的加载目录加载文件:'load   数据infile   '/var/opt/mysql-load/import.csv'进入   表......'

  6.   
  7. sudo aa-logprof aa-logprof将识别访问冲突   由'load data infile触发   ......'查询,并以交互方式引导你   通过允许将来访问。   你可能想从中选择Glob   菜单,以便您最终阅读   访问'/ var / opt / mysql-load / *'。   一旦你选择了正确的   (glob)模式,从中选择Allow   菜单完成。 (N.B.做   在提示时启用存储库   第一次跑步时这样做   aa-logprof,除非你真的   了解整个apparmor   过程)。

  8.   
  9. sudo aa-enforce / usr / sbin / mysqld

  10.   
  11. 尝试重新加载您的文件。这次应该可以工作。

  12.