1

私は、distinct() API 呼び出しでパフォーマンスの問題が発生する場合があることを読みました。個別の使用を回避した orm を使用してクエリを書き直そうとしました (少なくとも違いをプロファイルします)。

私の理解では、 values() は内部で Group By を実行します。ただし、2 つのメソッドをテストすると、distinct() を使用するか、values()/annotate() を使用するかによって、オブジェクトの数が異なります。

   zip_codes = Location.objects.values('zip_code').annotate(zip_count=Count('zip_code')).exclude(zip_code=None).count()

対。

  zip_codes = Location.objects.values_list('zip_code', flat=True).exclude(zip_code=None).distinct()

ここで何が間違っているかについて何か考えはありますか?

ありがとう!

4

1 に答える 1

2

同様のクエリを使用して、私が持っているデータベースに対してクエリをすばやくチェックしました。カウントは同じだったので、データの何が問題を引き起こしているのかわかりません。

私はまた、その前提に非常に懐疑的です。DISTINCT は確かに CPU を集中的に使用するクエリです。ただし、COUNT(*) も同様です。2 番目のクエリでは、最初に group by を使用して count 集計を実行し、次に結果に対して COUNT を実行します。私は、単一の DISTINCT 呼び出しが高速になることにお金をかけます (また、使用しているデータベースのバックエンドを確認します)。これらはすべて、django の ORM とはほとんど関係がなく、データベース バックエンドとはさらに多くの関係があります。

これについても考えてみてください。個別ベースのクエリは、注釈ベースのクエリと比較して、何を達成しているかが桁違いに明確です。あなたの状況で DISTINCT が遅くなることを裏付ける証拠はありますか、それとも現在ボトルネックを形成しているというよりも良いことですか? そうでない場合は、時期尚早の最適化の範囲に入っているため、パスを大幅に再検討する必要があります。

時期尚早の最適化

最適化は、重要な場合にのみ重要です。重要な場合は非常に重要ですが、重要であることがわかるまで、多くの時間を無駄にしないでください。重要だとわかっていても、どこが重要なのかを知る必要があります。パフォーマンス データがなければ、何を最適化すればよいか分からず、間違ったものを最適化する可能性があります。

結果はわかりにくく、書きにくく、デバッグしにくく、問題を解決しないコードを維持するのが難しくなります。したがって、(a) ソフトウェア開発とソフトウェア保守のコストが増加すること、および (b) パフォーマンスにまったく影響がないことの 2 つの欠点があります。

言い換えれば、ソフトウェアを明確に記述し、問題を見つけたらソースをたどって修正します。それ以前に何をしても逆効果です。データベースでどのインデックスが重要になるか、およびselect_relatedをどこで使用するかについて心配することに時間を費やしてください。これらは、ここで心配していることよりも 10000% 効果的です (常に郵便番号を数えている場合を除きます。その場合は、キャッシングについて紹介します)。

于 2011-08-26T18:40:15.417 に答える