2011-11-26 10 views
7

私は約2年間は正常に実行されているクエリを持っています。データベーステーブルには約5千万の行があり、ゆっくりと成長しています。この先週、私の質問のうちの1つは、ほぼ即座に復帰してから、何時間も実行するまでになりました。何年もの間単純なクエリが働いていて、突然非常に遅い

Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)).latest('id') 

私はランクモデルまでの低速クエリを絞りました。最新の()メソッドを使用することと関係があるようです。私がクエリーセットを求めたら、すぐに空のクエリーセットを返します。

#count returns 0 and is fast 
Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)).count() == 0 
Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)) == [] #also very fast 

EXPLAINを実行した結果は次のとおりです。 http://explain.depesz.com/s/wPh

し、分析EXPLAIN: http://explain.depesz.com/s/ggi

は、私はテーブル、変更なしの掃除をしようとしました。 「サイト」フィールド(ForeignKey)にはすでにインデックスがあります。

不思議なことに、奇妙なことに、私のアカウントに関連付けられたランクオブジェクトが既に存在する別のクライアントに対して同じクエリを実行すると、クエリは再び非常に迅速に戻ります。したがって、これは、そのクライアントのRankオブジェクトがない場合にのみ問題になると思われます。

アイデア?

バージョン: ジャンゴ1.4のsvnトランクは17047

答えて

0

実際、実際のSQLは表示されていないので、わかりにくいです。しかし、説明の出力は、一致を見つけるための最も速い方法が、問題のクライアントを見つけるまで "id"のインデックスを逆方向にスキャンすることであると考えています。

最近までは速かったと言われているので、これはおそらく馬鹿げた選択ではありません。しかし、常にこの検索の最後に特定のクライアントのレコードが正しく表示される可能性があります。

そう - 最初の二つのことを試してください:実行

  1. ANことがプランナーに十分な情報を与えるかどうかを確認し、問題のテーブルの上に分析します。
  2. そうでない場合は、問題の列の統計(ALTER TABLE ... SET STATISTICS)を増やして再分析してください。それがそれをするかどうかを確認してください。

http://www.postgresql.org/docs/9.1/static/planner-stats.html

それはまだ助けていない場合は、(クライアント、ID)にインデックスを考慮し、(他の場所で必要とされていない場合)のIDにインデックスをドロップします。それはあなたに雷の速い答えを与えるはずです。

+0

ORDER BYのWHEREフィールドとフィールドのフィールドに複合インデックスを設定することは、そのトリックを行いました。クエリプランナは、並べ替えのインデックス全体をスキャンしてから、フィルタを実行していました。化合物指数はトリックをしました。 – erikcw

0

latestsのを吹け のPostgres 9.1は、通常、日付の比較のために使用されている、多分あなたは、ID DESCで注文しようとする必要があり、その後、1に制限します。

+0

私はそれを試みましたが、同様に長い遅延もありました。 ORMによって生成された生のSQLを見ると、どちらも同等の出力が得られます。 – erikcw

関連する問題