首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django过滤查询在大行数据集中缓慢

Django过滤查询在大行数据集中缓慢
EN

Stack Overflow用户
提问于 2020-01-14 05:43:30
回答 1查看 3.5K关注 0票数 2
  • 在对以下字段数据执行大行筛选时,我的站点一直面临性能缓慢的问题。我在字段中存储的数据类型是RAW HTTP Response Bodybody字段中,其中包含大量内容,在Project模型下面有32k个对象。
代码语言:javascript
复制
class Project(models.Model):
    body = models.TextField(null=True,blank=True)
  • body上执行过滤只需几秒钟。
代码语言:javascript
复制
>>> Project.objects.filter(body__icontains='x').count() ### 5-6 seconds
20472

我使用Django分页器对每个页面的数据进行切片。

代码语言:javascript
复制
>>> from django.core.paginator import Paginator
>>> data = Project.objects.filter(body__icontains='x')
>>> p = Paginator(data,10)
>>> p.page(1) ### takes 5-6 seconds here again because this function counts the total number of pages based on data.count()
<Page 1 of 2048>
  • 然后,我将分页器数据传递给模板,该模板只是循环并显示主体。
代码语言:javascript
复制
{% for each_data in data %}
    {{ each_data.body }}
{% endfor %}
  • 对于分页器的每一页,等待5-6秒,因为paginator函数对整个数据集执行计数,并返回页面范围。这是最大的缺点。

使用常规Python切片:

代码语言:javascript
复制
>>> data = Project.objects.filter(body__icontains='x')
>>> for each_data in data[0:10]:  ### 0.1 seconds
        print(each_data.body)
  • 正如您所看到的,如果我们根本没有命中数据库,只需将数据切片并将其传递到模板上,那么它就会立即显示数据。
  • 我相信,当Paginator函数计算每个页面的过滤结果的总页数时,查询速度会变慢。
  • 我认为分页器不适合大数据集。

使用切片功能的缺点是:

  • 我们无法计算过滤器返回的结果对象的总数。
  • 无法看到分页器应有的页数,因为我们不计算整个数据集。

是否有任何方法来解决这个问题,以获得更快的结果和分页?

EN

回答 1

Stack Overflow用户

发布于 2020-01-14 12:02:32

为什么会发生这种事?

考虑一下这个例子:

代码语言:javascript
复制
Project.objects.filter(body__icontains='x').count()

这将被转换为这个查询(PostgreSQL):

代码语言:javascript
复制
SELECT COUNT(*) AS res
  FROM project
 WHERE UPPER(project.body::text) LIKE UPPER('%x%')

如果有很多记录,这将是非常缓慢的。@bruno建议--尝试找到一种优化它的方法(它可能取决于您的RDBMS)。

Django中的经典分页是通过限制和偏移SQL语句实现的。其结果是:

计数-(执行时间: 10.7s)

偏移量X - DB需要在进行适当排序后从磁盘读取X记录;如果已将新元素插入到已被请求的页面中,则无效元素列表。

通常,计数是散列的,当添加新记录时,我们只需进行更新。偏移量很难优化(缓存?)。

有没有更好的解决办法?

密钥集分页,算法如下:

  • 我们记住页面上第一个FIRST_TIMESTAMP和最后一个LAST_TIMESTAMP元素的标识符,例如,这可能是发布日期。
  • 为了获得下一页,我们使用的是构造:
代码语言:javascript
复制
WHERE table.date > LAST_TIMESTAMP ORDER_BY date ASC LIMIT <PAGE SIZE> 

优势:

  • 在大型查询集上工作得快得多。
  • 添加新元素时,正确地处理对前几页的更改。Django有几个实现

Disadvantages:

  • 如果没有预装数据,就不能切换到随机页面,这就是为什么它只适合无限滚动。

因此,如果是您的情况,您可以显着地加快分页。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59728094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档