1

基本的に、すべてのホストの最新の 30 個のログ エントリを取得したいと考えています。現在、私はdjango-pistonでこれを行っています。

def read(self,request):
    val={}
    for x in Host.objects.all():
        val[x.uuid_id]=DataLog.objects.filter(host=x).order_by('-time')[:30]           
    return val

残念ながら、このリクエストには時間がかかります (現在、約 10,000 のデータベース エントリに対して 1 秒)。これを行うためのより効率的な方法はありますか?

ハーパー

4

1 に答える 1

3

PostgreSQL をデータベースのバックエンドとして使用していて、データベース間の互換性が必要ない場合は、次のようなことを可能にする強力なウィンドウ関数を使用できます。

あなたのテーブルがそのように見えると想像してください:

CREATE TABLE x (
    i serial primary key,
    value integer not null,
    date timestamp,
    category text);

そして、各カテゴリの最新の値が必要です。あなたは〜をします :

SELECT
    first_value(i) over w,
    first_value(value) over w,
    first_value(date) over w
    category,
FROM x
WINDOW w AS (PARTITION BY category ORDER BY date DESC);

rawクエリ セット マネージャーのメソッドを使用して、django でこのようなクエリを使用できます。

ModelX.objects.raw("""SELECT DISTINCT ....... FROM x WINDOW w .....""")

カテゴリごとに最後の N エントリを取得するには、クエリがもう少し複雑になり、サブクエリが必要になります。

SELECT i, value, date, category
FROM (SELECT
        i, value, date, category,
        row_number() over w
    FROM x
    WINDOW w AS (PARTITION BY category ORDER BY date DESC)) AS subquery
WHERE subquery.row_number <= 30;

それを見て、ビューを作成することさえできます:

CREATE VIEW x_with_reverse_date_index AS
    (SELECT
        i, value, date, category,
        row_number() over w
    FROM x
    WINDOW w AS (PARTITION BY category ORDER BY date DESC));

そして、このビューをクエリする django モデルを作成します:

class ModelX(models.Model):
    ...
    ...
    row_number = models.IntegerField("Row number when ordering by date desc")

    class Meta:
        db_table = 'x_with_reverse_date_index'

そしてそれを「普通に」照会します:

ModelX.objects.filter(category__in = ('catA','catB'), row_number__lte = 30)
ModelX.objects.filter(row_number = 29)
...

警告: 繰り返しますが、別のデータベース エンジンで動作するコードが必要な場合は、これを行わないでください。

于 2012-05-22T08:52:53.183 に答える