2

このクエリは、グループごとの行数を制限するという、mysql では簡単にできないことをしようとしています。のリストがuser_id'sクエリに渡され、いくつかの断片が返されますが、グループはグループごとに 4 行に制限する必要があります。クエリは機能しますが、Sequel Pro によると 200 ~ 500 ミリ秒とやや遅くなります。

フラグを立てる前に読み続けてください!!

SELECT id, user_id, article_id, row_number
FROM (
    SELECT a2.id, a2.user_id, a2.post_id,
        @num:= if(@group = a2.user_id, @num + 1, 1) as row_number
    FROM (
        SELECT a1.id, a1.user_id, a1.post_id
        FROM articles as a1
        WHERE a1.user_id IN (3,14,1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,38,39,13,114,1111,12,223,2234,225,226,227,228,229,2210)
        ORDER BY a1.date DESC
    ) as a2, 
    (SELECT @num := 0) t
) as f
WHERE row_number <= 4;

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

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY <derived2>  ALL         NULL    NULL    NULL    NULL    10516   Using where
2   DERIVED <derived4>  system      NULL    NULL    NULL    NULL    1   
2   DERIVED <derived3>  ALL         NULL    NULL    NULL    NULL    10516   
4   DERIVED NULL        NULL        NULL    NULL    NULL    NULL    NULL    No tables used
3   DERIVED s1          ALL         Reco... NULL    NULL    NULL    1180931 Using filesort

これを複数のクエリに分割することを考えましたが、各グループの結果を 4 に制限するという問題がまだ発生しているようです。全体として、多くのクエリと高価なクエリを回避しようとしています。

このクエリを分割して一部をアプリケーションに移動することで、このクエリの速度を向上させる最善の方法についてのアイデアはありますか?

4

3 に答える 3

0

変数の使用を避けてこれを行うことは可能かもしれません。

テーブルをそれ自体に対して結合し、ユーザー ID と日付で結合して、日付が同じかそれ以降のすべての記事を検索します。次に、実際に必要なフィールドでグループ化された一致する記事の数を取得し、カウントが 4 を超える記事を破棄します。

このようなものでテストされていません。

SELECT a1.id, a1.user_id, a1.post_id, COUNT(a1_plus.id) AS other_count
FROM articles as a1
INNER JOIN articles a1_plus
ON a1.user_id = a1_plus.user_id
AND a1.date <= a1_plus.date
WHERE a1.user_id IN (3,14,1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,38,39,13,114,1111,12,223,2234,225,226,227,228,229,2210)
GROUP BY a1.id, a1.user_id, a1.post_id
HAVING other_count <= 4
于 2014-10-06T15:08:23.237 に答える