说,我们有两个模型,作者,书。要获得一些作者的最新书籍,我们可以:
选项1
def get_books1():
authors = Author.objects.filter(*condition*)
books = {}
for author in authors:
# maybe lots of queries
# simple query
book = Book.objects.filter(author=author).order_by("-pubdate")[:1]
if book:
book = book[0]
else:
continue
books.update({
"book.name": {
"name": book.name,
"pageno": book.pageno,
"pubdate": book.pubdate,
"author_name": author.name,
}
})
# we got books
选项2:
def get_books2():
authors = Author.objects.filter(*condition*)
# a complicated query, but only once
_books = Book.objects.filter(author__in=authors).order_by("-pubdate")
books = {}
# a complicated logic to process the data(ordering, discarding, etc.)
for book in _books:
if book not in books:
books[book.name] = {
"name": book.name,
"pageno": book.pageno,
"pubdate": book.pubdate,
"author_name": book.author.name,
}
else:
if book.pubdate > books.get(book.name).get("pubdate"):
books[book.name] = {
"name": book.name,
"pageno": book.pageno,
"pubdate": book.pubdate,
"author_name": book.author.name,
}
# we got books
如果此条件中有N位作者,我们对选项1有N + 1个查询, 而2个查询选项2。
对于性能(DB IO与内存处理),哪个应该是首选?我们应该总是选择选项2吗?或者它取决于N和系统(内存方式还是IO方式)?
感谢。
答案 0 :(得分:0)
来自QuerySets上的Django文档:
谨慎使用嵌套查询并了解数据库服务器的性能特征(如果有疑问,请使用基准测试!)。一些数据库后端,最着名的MySQL ,不能很好地优化嵌套查询。在这些情况下,提取值列表然后将其传递到第二个查询更有效。 即,执行两个查询而不是一个:
回答你的问题取决于数据库后端,表上的索引(参见你的Django模型/字段),等等。
在MySQL中,执行几个简单的SELECT查询有时会更快,而不是创建一个收集所有内容的庞大查询。如果您的作者条件将N缩小到较小的数字,则可能是选项1的性能优于选项2.可以说,您需要分析查询的性能并查看哪些表现更好。