我希望加快需要使用 distinct 的查询,因为它有一个 M2M 字段可供选择。在这一点上,我不确定我的速度问题是与我的数据库服务器配置方式有关,还是与我的查询集有关。
我的问题:什么是最快的查询集,我是否也可以通过更改我的 Postgresql 设置来提高速度?
Postgresql 服务器信息
实例:EC2 m1.xlarge
PostgreSQL 版本:9.1
文章记录:240,695
总内存:14980 MB
共享缓冲区:3617MB
有效缓存大小:8000MB
工作内存:40MB
检查点_段:10
维护工作内存:64MB
相关模型
class AuthorsModelMixin(models.Model):
authors = models.ManyToManyField('people.Person', blank=True)
nonstaff_authors = models.CharField(
verbose_name='Non-staff authors', max_length=255, blank=True,
help_text="Used for the name of the author for non-staff members.")
byline_title = models.CharField(
max_length=255, blank=True,
help_text="Often contains an organization. Title of the person, or " \
"entity associated with the byline and a specified person " \
"(i.e. Associated Press).")
class Meta:
abstract = True
class TaxonomyModelMixin(models.Model):
sections = models.ManyToManyField(Section, blank=True)
tags = TaggableManager(
blank=True, help_text='A comma-separated list of tags (i.e. ' \
'Outdoors, Election, My Great News Topic).')
class Meta:
abstract = True
class PublishModelMixin(models.Model):
status_choices = (
('D', 'Draft'),
('P', 'Published'),
('T', 'Trash'),
)
comment_choices = (
('enabled', 'Enabled'),
('disabled', 'Disabled'),
)
sites = models.ManyToManyField(Site, default=[1])
status = models.CharField(
max_length=1, default='P', db_index=True, choices=status_choices,
help_text='Only published items will appear on the site')
published = models.DateTimeField(
default=timezone.now, db_index=True,
help_text='Select the date you want the content to be published.')
is_premium = models.BooleanField(
choices=((True, 'Yes'), (False, 'No')),
verbose_name='Premium Content', default=True)
comments = models.CharField(
max_length=30, default='enabled',
choices=comment_choices, help_text='Enable or disable comments.')
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
objects = PublishedManager()
class Meta:
abstract = True
class Article(AuthorsModelMixin, TaxonomyModelMixin, PublishModelMixin):
title = models.CharField(max_length=255)
slug = SlugModelField(max_length=255)
lead_photo = models.ForeignKey('media.Photo', blank=True, null=True)
summary = models.TextField(blank=True)
body = models.TextField()
我试过的查询集
查询集 1
查询时间:(76 毫秒)
优点:速度快,发表的文章不会被显示
缺点:如果更高的 ID 具有更早的发布日期,那么文章列表将乱序
queryset = Article.objects \
.published() \
.filter(sections__full_slug__startswith=section.full_slug) \
.prefetch_related('lead_photo', 'authors') \
.order_by('-id') \
.distinct('id')
查询集 2
查询时间:(76 毫秒)
优点:文章始终井井有条
缺点:如果两篇文章的发布日期和时间相同,则只会列出一篇
queryset = Article.objects \
.published() \
.filter(sections__full_slug__startswith=section.full_slug) \
.prefetch_related('lead_photo', 'authors') \
.order_by('-published') \
.distinct('published')
查询集 3
查询时间:(1007 毫秒)
优点:文章始终井井有条,不会出现文章未列出的情况
缺点:慢得多!
queryset = Article.objects \
.published() \
.filter(sections__full_slug__startswith=section.full_slug) \
.prefetch_related('lead_photo', 'authors') \
.order_by('-id', '-published') \
.distinct('id')
查询集 4
查询时间:(4797.85 毫秒)
优点:不多,但不使用 DISTINCT ON
意味着它可以在其他数据库(如用于测试的 SQLite)上工作
缺点:慢得多!!!
queryset = Article.objects \
.published() \
.filter(sections__full_slug__startswith=section.full_slug) \
.prefetch_related('lead_photo', 'authors') \
.order_by('-published') \
.distinct()
最佳答案
你能尝试对这个查询进行性能测试吗?由于您尚未发布模型,请调整任何字段名称。
我们的想法是将它分成两部分:一个将返回查看中间表的所有文章 ID。
queryset = Article.objects \
.published() \
.filter(id__in=Article.sections.through.objects
.filter(section__full_slug__startswith=section.full_slug)
.values_list('article_id', flat=True)) \
.prefetch_related('lead_photo', 'authors') \
.order_by('-published', '-id')
关于django - 如何加速使用 .distinct() 的查询集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18517811/