シンプルバージョン:
Django の raw SQL が QuerySet インターフェースよりも効率的なのはなぜですか?
いくつかの詳細:
PostgreSQL データベースから ~ 700,000 (それ以上になる可能性があります) 行を返すクエリがあります。各行には、いくつかの double 値、いくつかの文字列、およびいくつかの整数が含まれています。したがって、適度に複雑なリターンです。
形式は単純です (単純化しすぎた例):
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()
「クエリ」は、クエリセットから生成された connection.queries コードの正確な文字列表現です。
更新 2:
タイミングはline_profiler
、最初のクエリから返されたタプルのリストまでの時間の合計を使用して実行されます (両方のオプションでまったく同じ結果が返されます)。生のクエリがデータベースで直接かかる時間もテストしました(両方ともまったく同じです)。タイミングの不一致は、各メソッドを介して python から実行される場合です。