【问题标题】:Increase speed for MySQL table creation in Django?提高在 Django 中创建 MySQL 表的速度?
【发布时间】:2011-01-02 18:12:44
【问题描述】:

我的一些单元测试需要 10-15 秒才能让 mysql 创建表。这似乎是不必要的长。它必须创建大约 50 个表,但每秒仍然只有 3 个表。当一遍又一遍地运行单元测试时,这是一个很大的烦恼。

作为一种解决方法,我一直在 sqlite3 中运行我的单元测试。它速度极快,但我更喜欢在 MySQL 上运行测试,因为这是我的实时服务器运行的。

为了说明速度差异,请创建一个新项目。然后使用 mysql 在其上运行 syncdb。然后用 sqlite3 试试。

[~/testproject] ./manage.py syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site

对我来说,在 MySQL 中创建上述表大约需要 2 秒。 Sqlite3 几乎是即时的。

我在我的开发机器上运行 mysql。这是我的my.cnf

请提出您能想到的任何可能有助于加快 MySQL 表创建时间的提示或调整。

【问题讨论】:

  • 你的 MySQL 表是本地的还是远程的?
  • 它在我的 Mac 上是本地的。如果你喜欢,请查看我的 my.cnf:pastebin.com/m69af8ba3
  • “我更愿意在 MySQL 上运行我的测试” 为什么?你不信任 Django ORM 层?
  • 我有一些执行原始 sql 以提高性能的代码。原始 sql 仅适用于 mysql。还有其他有效的用例,例如使用 mysql 全文搜索。
  • @andybak - 我很确定除了新的 settings.py 之外别无他法。如果 Django 可以选择为测试指定完全不同的数据库设置,那就太好了,但似乎没有。

标签: mysql django performance unit-testing django-models


【解决方案1】:

您可以创建 RAM 磁盘并将数据库移动到那里,仅用于单元测试。 如果你为此编写脚本,那么它是自动的,非常方便。

此外,出于其他目的,我编写了加载数据库的自定义测试运行程序 从 sql 转储而不是创建它然后创建表。

你选择。

【讨论】:

  • 我从来没有在 ram 磁盘上运行过 mysql,但我认为这就像在不同的端口上设置一个新的 mysql 守护程序并将其数据目录指向 ram 磁盘一样简单。感谢您的提示。
  • 是的,您也可以为现有的 mysql 实例切换配置(到 db 路径指向 ram 磁盘的配置),然后重新启动它 - 哪个更适合您。
  • 您是否真的在 ram 磁盘上运行了 mysql 并看到了速度提升?看起来它会有所帮助,但在你测试之前你真的不知道。
  • 是的,我自己完成了,并且体验到了显着的速度提升(虽然我没有测量时间来写出确切的数字)。
【解决方案2】:

我的 INNODB 表创建速度很慢(创建 13 个小表大约需要 25 秒)。

我尝试了 my.cnf 文件的 [mysqld] 部分中的选项。

添加:

innodb_flush_method=fdatasync

产生了最好的结果(创建相同的 13 个小表大约需要 1.5 秒)。

【讨论】:

    【解决方案3】:

    我发现使用 sqlite 作为替代品可以使我的单元测试更快。我还删除了 southdb,因为这也会减慢表的创建速度。

    if len(sys.argv) > 1 and sys.argv[1] == 'test':
        DATABASES = {
            'default': {
                'ENGINE': 'django.db.backends.sqlite3',
                'NAME': ':memory',
                'USER': '',
                'PASSWORD': '',
                'HOST': '',
                'PORT': '',
            }
        }
        INSTALLED_APPS = tuple([x for x in INSTALLED_APPS if x != 'south'])
    

    【讨论】:

    • 这是一种 hack,在执行高级数据库操作时可能会产生意想不到的结果(换句话说,当在 mysql 下失败时,您的测试可能会在 sqlite 下通过)。那个 sid,当您的生产服务器需要 mysql 时,这是一个快速进行测试开发的好解决方案。
    【解决方案4】:

    仅在 Mac OSX 上,将以下内容添加到您的 ~/.my.cnf:

    [mysqld]
    skip-sync-frm=ON
    

    对我来说,这将我在 MySQL 上的 Django 测试套件的启动时间从 1 分 30 秒缩短到了 7 秒!

    这里的详细信息: http://www.stereoplex.com/blog/speeding-up-django-unit-test-runs-with-mysql

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-14
      • 2014-10-19
      • 1970-01-01
      • 1970-01-01
      • 2015-06-21
      • 2017-11-03
      • 1970-01-01
      相关资源
      最近更新 更多