简单版:
为什么 Django 中的原始 SQL 比 QuerySet 接口更高效?
一些细节:
我有一个从 PostgreSQL 数据库返回约 700,000(可能更多)行的查询。每行包含一些双精度值、一些字符串和一些整数。所以一个适度复杂的回报。
它的形式很简单(过于简单的例子):
SELECT (a,b,c) FROM table WHERE d=something AND e=somethings ORDER BY a;
当我使用模型接口和 .filter() 进行查询时,查询的执行大约需要 30 秒。这是无法接受的。
我已经尝试使用所有建议的方法。(迭代器、内存高效迭代器等...)
connection.cursor
但是,当我使用...执行完全相同的查询时,fetchall
在 Django 中,查询的执行时间会下降到大约 5 秒。
使用 django 模型接口会产生什么开销来解释这种显着的性能差异?
更新:
Django 查询集代码:
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()
其中 'query' 是从 Queryset 生成的 connection.queries 代码的精确字符串表示形式。
更新 2:
计时是使用line_profiler
从初始查询到返回的元组列表的时间总和来完成的(两个选项的返回完全相同)。我还测试了原始查询直接在数据库上花费的时间(两者完全相同)。时间上的差异是通过每种方法从 python 完成的。