2012-03-27 46 views
1

私は2つのテーブルを持っています。複雑なPHPクエリ

books (id, sku, name, description, date_added) 

books_views (id, sku, date_viewed) 

私は次のことを行うために最適化されたクエリを記述しようとしています。

  1. はbooks_viewsテーブルは400万人以上のエントリーがあり、先月

のために最も見られた本を見つけるために先週

  • ための最も見られた本を見つけるために。週と月のビューでソートされたデータを取得するにはどうすればよいでしょうか?

  • +0

    保存されたビューの数はどこですか?何を試しましたか? – jordanm

    +0

    @jordanm:恐らく、各ビューの 'books_views'に新しい行が追加されています。 –

    +0

    new_rowがbook_viewsに追加されました。毎晩books_weekly_views(sku、count)のテーブルを作成してみましたが、それを使用していますが、効率的だとは思わないです。 – daydreamer

    答えて

    2

    クエリは次のとおりです。

    SELECT sku, count(*) AS times_viewed 
    FROM book_views bv 
    WHERE date_viewed > DATE_SUB(NOW(), INTERVAL 7 DAY) 
    GROUP BY sku 
    ORDER BY times_viewed DESC 
    

    30日までの間隔を変更するには、月のビューを取得するには。

    高速化するには、テーブルのインデックスが正しく作成されていることを確認する必要があります。 date_viewedのインデックスが必要です。ブック名が必要な場合は、両方のテーブルのsku列のインデックスを作成する必要があります。ここでは、どのようにして本の名前を得ることができます。 SKUとdate_viewedのPKでbooks_views (sku, date_viewed, views) - あなたのbooks_viewsテーブルでない限り

    SELECT bv.sku, name, count(*) AS times_viewed 
    FROM book_views bv JOIN books b ON bv.sku = b.sku 
    WHERE date_viewed > DATE_SUB(NOW(), INTERVAL 7 DAY) 
    GROUP BY bv.sku 
    ORDER BY times_viewed DESC 
    
    +0

    'times_viewed'にはどのようにインデックスを付けることができますか?エイリアスです。 –

    +1

    もちろん、私のdate_viewed。 – Rafe

    +0

    うまく動作しますが、約5.3秒かかります。それは大丈夫ですか? – daydreamer

    0

    は、あなたがあなたにあなたの意見テーブルを変更する必要があり、ここで表示されていない他のフィールドを持っています。その後

    DUPキーの挿入であるためにあなたのインサートを修正 -

    INSERT INTO books_views VALUES ('sku', CURRENT_DATE, 1) 
        ON DUPLICATE KEY UPDATE views = views + 1; 
    

    あなたが最高のパフォーマンスをしたい場合は、あなたができる挿入より更新を仮定 -

    UPDATE books_views 
    SET views = views + 1 
    WHERE sku = 'sku' 
    AND date_viewed = CURRENT_DATE; 
    

    、その後の確認影響を受ける行の数を計算し、影響を受けていない行がない場合は挿入します。 -

    INSERT INTO books_views VALUES ('sku', CURRENT_DATE, 1);