python - 做一些 python 分析后,Django(?)对大型数据集真的很慢

标签 python django optimization

我正在将我的旧 PHP 脚本与更新、更高级的 Django 版本和 PHP 脚本进行比较,完全吐出 HTML,并且所有功能都运行得更快。快得多,以至于 Django 一定有问题。

首先,了解一些背景信息:我有一个显示销售数据报告的页面。数据可以按多种方式过滤,但主要按日期过滤。这使得缓存它有点困难,因为结果的可能性几乎是无穷无尽的。完成了很多数字和计算,但在 PHP 中处理从来都不是什么大问题。

更新:

  • 经过一些额外的测试后,我认为没有任何原因导致速度下降。如果我只是对数据进行数字运算并吐出 5 行呈现的 HTML,它并没有那么慢(仍然比 PHP 慢),但如果我呈现大量数据,它就会非常慢。

  • 每当我运行一个大型报表(例如全年的所有销售额)时,机器的 CPU 使用率都会达到 100%。不知道这是否意味着很多。我正在使用 mod_python 和 Apache。也许切换到 WSGI 可能有所帮助?

  • 我的模板标签显示了从 0.1 秒到 1 秒的非常大的集合的小计/总计过程。我在报告中给他们打了大约 6 次电话,所以他们似乎不是最大的问题。

现在,我运行了一个 Python 分析器并返回了这些结果:

Ordered by: internal time
   List reduced from 3074 to 20 due to restriction 

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  2939417   26.290    0.000   44.857    0.000 /usr/lib/python2.5/tokenize.py:212(generate_tokens)
  2822655   17.049    0.000   17.049    0.000 {built-in method match}
  1689928   15.418    0.000   23.297    0.000 /usr/lib/python2.5/decimal.py:515(__new__)
 12289605   11.464    0.000   11.464    0.000 {isinstance}
   882618    9.614    0.000   25.518    0.000 /usr/lib/python2.5/decimal.py:1447(_fix)
    17393    8.742    0.001   60.798    0.003 /usr/lib/python2.5/tokenize.py:158(tokenize_loop)
       11    7.886    0.717    7.886    0.717 {method 'accept' of '_socket.socket' objects}
   365577    7.854    0.000   30.233    0.000 /usr/lib/python2.5/decimal.py:954(__add__)
  2922024    7.199    0.000    7.199    0.000 /usr/lib/python2.5/inspect.py:571(tokeneater)
   438750    5.868    0.000   31.033    0.000 /usr/lib/python2.5/decimal.py:1064(__mul__)
    60799    5.666    0.000    9.377    0.000 /usr/lib/python2.5/site-packages/django/db/models/base.py:241(__init__)
    17393    4.734    0.000    4.734    0.000 {method 'query' of '_mysql.connection' objects}
  1124348    4.631    0.000    8.469    0.000 /usr/lib/python2.5/site-packages/django/utils/encoding.py:44(force_unicode)
   219076    4.139    0.000  156.618    0.001 /usr/lib/python2.5/site-packages/django/template/__init__.py:700(_resolve_lookup)
  1074478    3.690    0.000   11.096    0.000 /usr/lib/python2.5/decimal.py:5065(_convert_other)
  2973281    3.424    0.000    3.424    0.000 /usr/lib/python2.5/decimal.py:718(__nonzero__)
   759014    2.962    0.000    3.371    0.000 /usr/lib/python2.5/decimal.py:4675(__init__)
   381756    2.806    0.000  128.447    0.000 /usr/lib/python2.5/site-packages/django/db/models/fields/related.py:231(__get__)
   842130    2.764    0.000    3.557    0.000 /usr/lib/python2.5/decimal.py:3339(_dec_from_triple)

tokenize.py 排在首位,这在我进行大量数字格式化时可能有一定意义。 Decimal.py 有意义,因为报告基本上是 90% 的数字。我不知道内置方法 match 是什么,因为我没有在我自己的代码中做任何正则表达式或类似的事情(Django 在做什么?)最接近的是我正在使用 itertools ifilter。

看来这些是罪魁祸首,如果我能弄清楚如何减少它们的处理时间,那么我的页面就会快得多。

有人对我如何开始减少这种情况有任何建议吗?我真的不知道如何在不简单地删除它们的情况下解决这个标记化/十进制问题。

更新:我对大部分数据运行了一些带/不带过滤器的测试,结果时间几乎相同,后者快一点但不是问题的原因。 tokenize.py 到底发生了什么?

最佳答案

由于您没有任何类型的代码示例,因此有很多事情可以假设您的问题。

这是我的假设:您正在使用 Django 的内置 ORM 工具和模型(即 sales-data = modelobj.objects().all() ),而在 PHP 端,您正在处理直接的 SQL 查询并使用一个查询集。

Django 正在对从数据库查询到 ORM/Model 对象和相关管理器(默认为 objects())的数据类型进行大量类型转换和转换。

在 PHP 中,您控制着转换并确切地知道如何从一种数据类型转换为另一种数据类型,您仅基于该问题就可以节省一些执行时间。

我建议尝试将一些花哨的数字工作转移到数据库中,特别是如果您正在进行基于记录集的处理 - 数据库从早餐中吃掉了这种处理。在 Django 中,您可以将 RAW SQL 发送到数据库:http://docs.djangoproject.com/en/dev/topics/db/sql/#topics-db-sql

我希望这至少能让你指明正确的方向......

关于python - 做一些 python 分析后,Django(?)对大型数据集真的很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1173798/

相关文章:

python - Arduino 串行命令独立工作,但组合时没有任何反应

python - Django 1.7 makemigrations 不工作 - 没有名为的列

Django模型时间范围过滤方法

regex - 如何优化 grep 正则表达式以匹配 URL

python - 将标志作为参数传递给 re.compile

python - 如何修复 "IndexError: list index out of range"

algorithm - 根据给定的标准找到图中两个节点之间的路径 - 优化任务

MySQL查询优化帮助

python - 在 Python 中重写 set 方法

python - django-admin makemessages : how does it work with txt, xml 和其他文件?