如果我需要查询集中的所有对象以及来自这些对象的一组字段值,考虑速度和应用程序内存使用情况,哪个选项会更好(我使用的是PostgreSQL后端) :
选项a:
def get_data():
queryset = MyObject.objects.all()
total_objects = queryset.count()
thumbs = queryset[:5].values_list('thumbnail', flat=True)
return {total_objects:total_objects, thumbs:thumbs}
选项b:
def get_data():
objects = list(MyObject.objects.all())
total_objects = len(objects)
thumbs = [o.thumbnail for o in objects[:5]]
return {total_objects:total_objects, thumbs:thumbs}
如果我理解正确,如果我错了肯定会纠正我:
选项a:它会在数据库中命中两次,并且只会在内存中产生total_objects = integer和thumbs =字符串列表。
选项b:它会一次点击数据库,并会生成所有对象及其所有归档数据的列表+选项内存中的项目。
考虑到这些选项并且可能存在数百万个MyObject实例:一个数据库的速度是打击的(选项a)是否优于单个数据库命中的内存消耗(选项b)?
我的首要任务是返回数据的整体速度,但我担心更大的内存消耗会使得速度下降甚至超过额外的数据库命中率。
答案 0 :(得分:1)
使用SQL是最快的方法,并且总是胜过Python等价物,即使它更多地访问数据库。相比之下,差异可以忽略不计。请记住,这就是SQL 意味着要做的事情 - 快速而有效。
无论如何,使用timeit运行一千个循环,结果如下:
In [8]: %timeit get_data1() # Using ORM
1000 loops, best of 3: 628 µs per loop
In [9]: %timeit get_data2() # Using python
1000 loops, best of 3: 1.54 ms per loop
如您所见,第一种方法每个循环需要628微秒,而第二种方法需要1.54 毫秒。这几乎是2.5倍!一个明显的赢家。
我使用的SQLite数据库中只包含100个对象(我使用autofixture对模型进行垃圾邮件)。我猜PostgreSQL将返回不同的结果,但我仍然赞成第一个。