2012-01-10 2 views
0

以下の結果は4 dbヒットになります。 3行目& 4は、2行目でフィルタリングしたものだけをフィルタリングしているので、変更する必要がありますので、dbに再度ヒットしません。Djangoの_setsを最適化してクエリを減らす

page = get_object_or_404(Page, url__iexact = page_url) 
installed_modules = page.module_set.all() 
navigation_links = installed_modules.filter(module_type=ModuleTypeCode.MODAL) 
module_map = dict([(m.module_static_object.key, m) for m in installed_modules]) 
+0

'installed_modules ='に '.all()'メソッドが含まれているのはなぜですか?さらに、なぜあなたは辞書を作っていますか?このコレクションでさらに何が起こるでしょうか? –

+0

@ S.Lottこれははるかに大きな機能の一部です。何が後になるのかにかかわらず、私はこれらの行を最適化しようとしているので、dbを2回以上ヒットしません。一度ページオブジェクトをつかんで、関連するモジュールをそのページにつかみます。次に、関連セットを使ってdictなどを構築することができます。私はこのページに関連するすべてのモジュールを取得するためにallを使用しています。しかし、それが不要な場合は、削除します。 – Brenden

+0

'navigation_links = installed_modules.filter(module_type = ModuleTypeCode.MODAL)について.select_related( 'module_static_object__key')'? [select_relatedについて詳しくはこちら](https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related) – danihp

答えて

4

ジャンゴquerysets are lazy、次の行には、データベースにヒットしないように:

あなたはこの行のクエリセットを反復処理するまで、クエリが実行されません
installed_modules = page.module_set.all() 

:だから

module_map = dict([(m.module_static_object.key, m) for m in installed_modules]) 

あなたが投稿したコードは私には3つのデータベースクエリのようにしか見えません4.

データベースからすべてのモジュールを取得しているので、

navigation_links = [m for m in installed_modules if m.module_type == ModuleTypeCode.MODAL] 

このパフォーマンスが向上したかどうかを確認するには、ベンチマーキングを行う必要があります。それは私にとっては時期尚早の最適化である可能性があります。

module_static_object.keyをフェッチするモジュールごとに1つのデータベースクエリを実行している可能性があります。この場合、select_relatedを使用できます。

+0

私が探していたもの。ありがとうございました! – Brenden

1

これは早すぎる最適化の場合である。 4ページの負荷に対するDBクエリは悪くありません。できるだけ少ない数のクエリを使用するというアイデアがありますが、すべてのシナリオで1つに減らすことは決してありません。あなたがそこに持っているコードは、不必要にクエリを作成するという意味で壁のようには見えないので、それを作ることができるように既に最適化されている可能性は非常に高いです。

+0

クエリがどれほど高価であるかをどのように知っていますか?彼が尋ねた質問は合理的です。 – jknupp

+0

Chris - これはかなり長い機能の始まりです。関数内のすべてのクエリを見ると、これが最も保存できる場所だと思います。それが私が最適化しようとしている理由です。 – Brenden

+0

ここで重要なのは、実際に貯蓄がないということです。最初のページオブジェクトを取得することは、それ自身のクエリです。 'installed_modules'を取得することは別の問い合わせです。 'navigation_links'を取得することは、installed_modulesからリストの理解を作成するようなことをしない限り、(install_modulesのクエリを構築しているにもかかわらず)必ず別のクエリです。それはクエリを保存しますが、クエリーセットではなく静的なリストを残します。ほとんどの場合、1つのクエリを保存します。これは、機能が失われていることを考慮して、グランドスキームではほとんど意味がありません。 –