2016-09-16 4 views
0

データベースからk個のランダムな行を選択する必要があります。私たちは(それほど革新的ではない)、この思い付いたpostgresからk個のランダムな行を選択するdjango ORM

table.objects.filter(..).order_by('?')[:k] 

が、その後、私たちは、これは非常に非効率的なソリューションであることを、インターネット上で読む: - - : だから、私たちのintialの思考は次のように起こっていた

しかしこれはこれまでよりも遅いようです。

私たちは、正確に選択するための正しいアプローチが何であるかを知りたがっています。我々のケースではpostgresであるデータベースから正確にk行です。

+0

[:k]は、自動的にSQLにLIMITを設定するため、良いアプローチです。 – sebb

+1

'order_by( '?')'は大きなテーブルでは非常に遅いです。 'max_id'を取り出して、Pythonコードの' 1、...、max_id'の集合から 'k'個の数字を選ぶ方が速いです。 – Tobias

+0

2番目の方が効率的ではありません。なぜなら、必要なkだけでなく、すべての一致する行をフェッチするからです。 –

答えて

0

ダニエルローズマンはコメントで述べたように、あなたがそのクエリセットのうちのkを見つけ、その後、すべてオブジェクトをフェッチする必要があると思いますので、

が遅い理由は、あります。

私は正確に問題の同じ種類に遭遇したと我々は解決方法は、このテーブル内のmax_idを探す

  • にしました。
  • table.objects.filter(id__in=set_of_ks)

このコースのテーブルIDのセットには「穴」が存在しないことを前提としています1, ..., max_id

  • のセットからk番号を選択します。

  • +0

    しかし、それは2つのクエリを実行しますか? –

    +0

    はい、しかし、 'max_id'をフェッチすることは一定の時間に行われるべきですので、(非常に)高速です。次のクエリは、あなたがとにかくやらなければならない行です。 – Tobias

    0

    テーブルのサイズがおおよそわかっている場合は、新しいTABLESAMPLE句を使用してランダムに行の割合を選択できます。その後、いつでもそれを制限することができます。

    それをカバーする短いブログ記事​​。

    関連する問題