2011-07-04 5 views
107

結果:ジャンゴ - 制限クエリは、私は、モデルの最後の10個のインスタンスを取得し、このコードを持ちたい

Model.objects.all().order_by('-id')[:10] 

は、それは、まずすべてのインスタンスをピックアップし、その後、わずか10最後のものを取るというのは本当でしょうか? これ以上有効な方法はありますか?

+4

https://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysets –

+0

右。私はこれをどこかで逃した。 – krzyhub

答えて

184

Djangoクエリーセットは遅延です。これは、具体的に結果を求めた場合にのみ、クエリがデータベースにヒットすることを意味します。

クエリの結果を印刷するか、実際に使用するまでは、データベースにアクセスしなくてもさらにフィルタリングできます。

以下に示すように、コードでは1つのSQLクエリのみが実行され、最後の10個のアイテムのみがフェッチされます。

In [19]: import logging         
In [20]: l = logging.getLogger('django.db.backends')  
In [21]: l.setLevel(logging.DEBUG)      
In [22]: l.addHandler(logging.StreamHandler())  
In [23]: User.objects.all().order_by('-id')[:10]   
(0.000) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" ORDER BY "auth_user"."id" DESC LIMIT 10; args=() 
Out[23]: [<User: hamdi>] 
22

実際、私はLIMIT 10がデータベースに発行され、スライスはPythonではなくデータベース内で行われると思います。

詳細については、limiting-querysetsを参照してください。

-3

いいえ、ドキュメントにはっきりと説明されているとおり、そうではありません。

8

問題の解決策はもうDjangoの1.7では動作しませんように見えるし、エラーを発生させます: は

を「クエリの順序を変更することはできません一度スライスが取られている」強制ドキュメントhttps://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysetsによると、 Pythonスライス構文の "step"パラメータはクエリを評価します。

さらに制限がSQLまたはPythonスライスで実行されているかどうかは、結果配列全体が返されます。巨大なリストをアプリケーションメモリに取り出すのは良いことではありません。

+0

このソリューションでさえ、django> = 1.8が動作しても動作しません。 –

-8

これは実際には起こりません。 Djangoは必要な結果だけをフェッチしません。 Djangoは完全なデータベーステーブルをロードします(これはstup [id]のことです)、最後の10個のレコードだけを返します。

MySQLサーバーでSHOW FULL PROCESSLISTを実行してこれを確認しましたが、クエリにはLIMIT句がありません。

高いスケーラビリティが必要な大規模なアプリケーションを開発する場合、Djangoは良い選択ではありません。

+3

これを証明するための追加情報を提供してください。一番上の回答は、Djangoが実行中のものとしてログに記録されている制限を示しています。私はちょうどこれがDjango 1.10に当てはまることを確認しました。クエリが非常に短くて表示されなかったため、完全なプロセスリストを表示できませんでした。 http://stackoverflow.com/questions/650238/how-to-show-the-last-queries-executed-on-mysqlのようにクエリログをオンにすると、MySql(または具体的にはMariaDB)にはクエリに制限条項。あなたはそれが怠惰に読み込むことができるようにクエリを実行していませんか? – Foon

関連する問題