假设我想在一个包含1M记录的表中获取返回大约10k条记录的查询的最后50条记录。我能做(以订购的计算成本):
data = MyModel.objects.filter(criteria=something).order_by('-pk')[:50]
我也可以(以2次数据库命中为代价):
# assume I don't care about new records being added between
# the two queries being executed
index = MyModel.objects.filter(criteria=something).count()
data = MyModel.objects.filter(criteria=something)[index-50:]
对于只有criteria
没有索引的普通关系数据库哪个更好(例如我的情况下是postgres;没有柱状存储或任何花哨的东西)?最重要的是, 为什么?
如果表或查询集明显更大(例如10M行表中的100k记录),答案是否会改变?
答案 0 :(得分:5)
这个会很慢
data = MyModel.objects.filter(criteria=something)[index-50:]
为什么因为它转化为
SELECT * FROM myapp_mymodel OFFEST (index-50)
您没有在此强制执行任何排序,因此服务器将不得不对结果集进行计算并跳转到结尾,并且这将涉及大量读取并且将非常慢。我们不要忘记count()查询也不是那么热。
其他,这个会很快
data = MyModel.objects.filter(criteria=something).order_by('-pk')[:50]
您在主键上反向排序并获得前50个。而前50个您可以使用
快速获取data = MyModel.objects.filter(criteria=something).order_by('pk')[:50]
所以这就是你真正应该做的事情
data1 = MyModel.objects.filter(criteria=something).order_by('-pk')[:50]
data2 = MyModel.objects.filter(criteria=something).order_by('pk')[:50]
主键订购的成本非常低。