0

3 つのテーブル (例 a、b、c) があり、さまざまな項目 (コメント、いいねなど) のアクティビティと、各アクティビティの時間を示します。私は基本的に、最新のアクティビティを最初に表示する一種のニュース フィードを作成しようとしています。3 つのテーブルすべてに対して UNION ALL を作成して、すべてのアクティビティをグループ化し、次に GROUP BY を作成して、同じアイテムのアクティビティが 2 回表示されないようにし、時間 DESC で並べ替えます。この関数は無限スクロールを使用するため、クエリも適切にシフトできる必要があります。

これを最適化する方法があるかどうか疑問に思っています (各テーブルは約 500 ~ 900K であり、増加しています)。切り捨てられたコードを以下に示します。

SELECT time,item_id FROM (
   SELECT a.time AS time, a.item_id FROM a 
      UNION ALL 
   SELECT b.time AS time, b.item_id FROM b 
      UNION ALL 
   SELECT c.time AS time, c.item_id FROM c
) temp 
GROUP BY item_id 
ORDER BY time DESC 
LIMIT 10
4

1 に答える 1

0

作成したクエリは、非常に大きな一時テーブルを作成します。次に、その一時テーブルの列で並べ替えています。おそらく次のように、各テーブルを制限するようにしてください。

SELECT time,item_id FROM (
   SELECT a.time AS time, a.item_id FROM a LIMIT 10 ORDER BY time DESC 
      UNION ALL 
   SELECT b.time AS time, b.item_id FROM b LIMIT 10 ORDER BY time DESC 
      UNION ALL 
   SELECT c.time AS time, c.item_id FROM c LIMIT 10 ORDER BY time DESC 
) temp 
GROUP BY item_id 
ORDER BY time DESC 
LIMIT 10

time各テーブルにインデックスがあることを確認する必要があります。

ただし、結果を正確に「スクロール」するのが難しい場合があるため、これを行うのはあまり好きではありません。

「次のページ」に移動するとき、代わりに のWHEREような句を追加することを検討することをお勧めします。それは精度に役立ちます。WHERE a/b/c.item_id > numLIMIT offset, length

クエリを記述するときは、クエリがどのようEXPLAINに処理されているかを確認するために、クエリの前に を付ける必要があります。これにより、何が起こっているかをよりよく理解できます。一時テーブルは作成されていますか? どのくらいの大きさですか?どのインデックスが使用されていますか? 等...

もう 1 つの方法は、MySQL トリガーを使用して単一の「フィード」テーブルにデータを入力することです。

于 2013-08-10T23:12:09.260 に答える