しばしば、私はDjangoのクエリーセットから最初のオブジェクトを取得したい場合があります。ない場合はNone
を返します。これを行うには多くの方法がありますが、それはすべて機能します。しかし、私はどの演奏家が演奏しているのか不思議です。djangoのクエリーセットから最初のオブジェクトを取得する最速の方法は?
qs = MyModel.objects.filter(blah = blah)
if qs.count() > 0:
return qs[0]
else:
return None
この結果、2回のデータベース呼び出しが行われますか?それは無駄に思える。これはもっと速いですか?
qs = MyModel.objects.filter(blah = blah)
if len(qs) > 0:
return qs[0]
else:
return None
別のオプションは、次のようになります。
qs = MyModel.objects.filter(blah = blah)
try:
return qs[0]
except IndexError:
return None
これは良いですが、単一のデータベース呼び出しを生成します。しかし、多くの場合、例外オブジェクトを作成する必要があります。これは、本当に必要なものが簡単なif-testである場合に、非常にメモリを消費することです。
例外オブジェクトを使用してメモリを混乱させることなく、単一のデータベース呼び出しでこれを行うにはどうすればよいですか?
DBの往復を最小限に抑えることを心配している場合は、クエリセットで 'len()'を使わないでください。常に '.count()'を使用してください。 –
"非常にメモリ集約的なものですが、多くの時間をかけて例外オブジェクトを作成します" - 例外が1つ発生することが懸念される場合は、Pythonが例外をすべて使用するため、間違っています。実際にあなたのケースではメモリを大量に消費することをベンチマークしましたか? – lqc
@Leopdそして、もしあなたがアンウォースを実際にベンチマークしたのであれば、それはそれほど速くはないことが分かります。それは実際には遅くなるかもしれません。あなたがそれを投げ捨てるだけの余分なリストを作成するからです。 Python関数を呼び出すかDjangoのORMを使うのと比べると、ちょうどピーナッツです! filter()への1回の呼び出しは、多くの場合、多くの場合、*多く*遅くなり、例外が発生します(これはまだ起こりそうですが、それがイテレータプロトコルの仕組みです)。 – lqc