为什么通过django查询比仅仅在django中使用光标慢得多?

为什么通过django查询比仅仅在django中使用光标慢得多?,django,postgresql,django-queryset,Django,Postgresql,Django Queryset,简单版本: 为什么Django中的原始SQL比QuerySet接口更高效 一些细节: 我有一个从PostgreSQL数据库返回700000(可能更多)行的查询。每行包含几个双精度值、一些字符串和一些整数。因此,这是一个中等复杂的回报 其形式简单(过于简化的示例): 当我使用model接口和.filter()进行查询时,查询的执行大约需要30秒。这是不能接受的 我试过使用所有建议的方法。(迭代器、内存高效迭代器等) 但是,当我使用connection.cursor执行完全相同的查询时。。。在Dja

简单版本:

为什么Django中的原始SQL比QuerySet接口更高效

一些细节:

我有一个从PostgreSQL数据库返回700000(可能更多)行的查询。每行包含几个双精度值、一些字符串和一些整数。因此,这是一个中等复杂的回报

其形式简单(过于简化的示例):

当我使用model接口和.filter()进行查询时,查询的执行大约需要30秒。这是不能接受的

我试过使用所有建议的方法。(迭代器、内存高效迭代器等)

但是,当我使用
connection.cursor
执行完全相同的查询时。。。在Django中,查询将下降到大约5秒执行

使用django模型接口会产生什么开销来解释这种显著的性能差异

更新:

Django查询集代码:

fast版本中完全相同的查询:

# OPEN a cursor
cursor = connection.cursor()

# EXECUTE the query
cursor.execute(query)
transaction.commit_unless_managed()

# FETCH all the rows
rows = cursor.fetchall()
其中,“query”是从Queryset生成的connection.queries代码的精确字符串表示形式

更新2:


使用
line_profiler
完成计时,并获取从初始查询到返回的元组列表的时间总和(两个选项的返回完全相同)。我还测试了原始查询直接在数据库上花费的时间(两者完全相同)。时间上的差异是通过每个方法从python完成的。

如果您对问题的更新中的两个代码段进行了计时,那么是的,差异是因为django正在将DB查询的结果编组到700000个python对象中(即,它调用了
对象。\ uu init\ uuu()
700000次)

使用原始sql进行查询没有任何问题。在这种情况下,根据您对信息的处理方式,可能会建议您这样做


也就是说。。。。响应中是否需要700000个对象?dict中的700000项是否会被替换(这就是原始sql查询返回的结果)?或者您可以通过分页或查询集切片限制返回的行数吗?

如果您对问题的更新中的两个代码段进行计时,那么是的,区别在于django正在将DB查询的结果编组到700000个python对象中(即,它正在调用
对象。\uu init\uuu()
700000次)

使用原始sql进行查询没有任何问题。在这种情况下,根据您对信息的处理方式,可能会建议您这样做



也就是说。。。。响应中是否需要700000个对象?dict中的700000项是否会被替换(这就是原始sql查询返回的结果)?或者您可以通过分页或查询集切片来限制返回的行数吗?

您可以给我们提供您使用的django ORM代码吗?因为在不知道你到底做了什么的情况下,我们确实无法判断是django的错还是你的错@danihp:是的,这可以解释为什么结果很差。你是如何衡量查询持续时间的?额外的时间是否会将数据编组到python对象/django模型中?我会投票结束这个问题,但“不是一个真正的问题”现在不是结束它的选项。添加了一个测量查询时间的更新@danihp这怎么不是一个真正的问题?我在问为什么一种方法在执行相同任务时比另一种方法慢得多。这正是我所做的。我从c_layer_points获取生成的查询,并用这两种方法测试了确切的字符串。我直接通过psql接口测试它,然后使用上述两种方法通过django进行测试。差异在于每个方法的时间——已知的数据库时间。您能给我们您使用的django ORM代码吗?因为在不知道你到底做了什么的情况下,我们确实无法判断是django的错还是你的错@danihp:是的,这可以解释为什么结果很差。你是如何衡量查询持续时间的?额外的时间是否会将数据编组到python对象/django模型中?我会投票结束这个问题,但“不是一个真正的问题”现在不是结束它的选项。添加了一个测量查询时间的更新@danihp这怎么不是一个真正的问题?我在问为什么一种方法在执行相同任务时比另一种方法慢得多。这正是我所做的。我从c_layer_points获取生成的查询,并用这两种方法测试了确切的字符串。我直接通过psql接口测试它,然后使用上述两种方法通过django进行测试。差异在于每个方法的时间-已知的数据库时间。与响应中的所有对象关联。一个远程MATLAB客户端正在联系数据库获取数据,然后使用实际数据进行某些操作。使用原始sql,我们已经将时间缩短到合理的程度。如果数据是为远程客户端收集的,那么您肯定不需要python对象。简单的口述完全可以满足你的需要。我不太清楚你所说的“简单口述”是什么意思。如果您引用的是原始查询返回的结果,那么是的,您是正确的,这就是我们选择的路径。不需要Django对象。如果不是,你指的也是什么?我指的是一个用字符串表示键和值的dict。事实上,我之前误导了您:Model.objects.raw()返回对象的查询集。以字符串形式返回DB内容的东西是。很抱歉给你带来了困惑。和迟来的回复。都与响应中的所有对象关联。一个远程MATLAB客户端正在联系数据库获取数据,然后使用实际数据进行某些操作。使用原始sql,我们已经将时间缩短到合理的程度。如果数据是为远程客户端收集的,那么您肯定不需要python对象。简单的口述完全可以满足你的需要。我不太清楚你所说的“简单口述”是什么意思。如果您所指的是原材料的退货
c_layer_points = models.layer_points.objects.filter(location_id__location_name=region,season_id__season_name=season,line_path_id=c_line_path.pk,radar_id=c_radar.pk,gps_time__gte=start_gps,gps_time__lte=stop_gps).order_by('gps_time').values_list('gps_time','twtt','pick_type','quality','layer_id')
# OPEN a cursor
cursor = connection.cursor()

# EXECUTE the query
cursor.execute(query)
transaction.commit_unless_managed()

# FETCH all the rows
rows = cursor.fetchall()