我有一些查询占用了我在生产中的大部分数据库访问时间,我想优化它们。这很复杂,因为生产中会出现执行缓慢,但不会出现在较小的本地数据集中。基于一些阅读,我开始相信问题是__in
条款。
这些问题部分遵循相同的一般模式:切出一些相关对象,然后运行一个大__in
查询来获取我的工作对象以供以后分析。 (引人注目的是,他们是这种模式的唯一部分)。根据我阅读here的内容,查询的__in
部分是个问题。答案说postgres在查找中运行顺序扫描,并且可以通过连接加速。这解释了生产中的差异,但是将原始SQL作为解决方案编写似乎是应该成为常见用例的红旗。
一些示例模型:
class Book(models.Model):
COLOR_CHOICES = (
(RED, 'Red'),
(BLUE, 'Blue'),
(GREEN, 'Green'),
)
color = models.IntegerField(
choices=COLOR_CHOICES,
default=RED
)
published = models.DateField()
author = models.CharField()
class Page(models.Model):
book = models.ForeignKey('Book')
text = models.TextField()
page_number = models.IntegerField()
如果我想按照颜色获得最近100本书的第一页,我会做类似的事情
#Get first pages of 100 most recently published books by color
reds = Book.objects.filter(color=Book.RED).order_by('-published')[:100]
greens = Book.objects.filter(color=Book.GREEN).order_by('-published')[:100]
blues = Book.objects.filter(color=Book.BLUE).order_by('-published')[:100]
books = list(itertools.chain(reds, greens, blues))
pages = Page.objects.filter(page_number=1, book__in(books))
并且查询的相关部分显示为
WHERE "page"."book_id" IN (%s, %s, ...)
而不是优化的连接。链接的答案是否正确in()查询子句可以改进,以及Django官方路由是做什么的?