次のデータベース設定があるとします(実際に持っているものから簡略化されたバージョン):
Table: news_posting (500,000+ entries)
| --------------------------------------------------------------|
| posting_id | name | is_active | released_date | token |
| 1 | posting_1 | 1 | 2013-01-10 | 123 |
| 2 | posting_2 | 1 | 2013-01-11 | 124 |
| 3 | posting_3 | 0 | 2013-01-12 | 125 |
| --------------------------------------------------------------|
PRIMARY posting_id
INDEX sorting ON (is_active, released_date, token)
Table: news_category (500 entries)
| ------------------------------|
| category_id | name |
| 1 | category_1 |
| 2 | category_2 |
| 3 | category_3 |
| ------------------------------|
PRIMARY category_id
Table: news_cat_match (1,000,000+ entries)
| ------------------------------|
| category_id | posting_id |
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 2 | 2 |
| 3 | 2 |
| 1 | 3 |
| 2 | 3 |
| ------------------------------|
UNIQUE idx (category_id, posting_id)
私のタスクは次のとおりです。アクティブで、今日の日付より前で、リクエストで指定された 20 ほどのカテゴリの 1 つにある 50 件の最新のニュース投稿 (あるオフセットで) のリストを取得する必要があります。返す 50 件のニュース投稿を選択する前に、適切なニュース投稿をトークンで降順に並べ替える必要があります。私のクエリは現在、次のようになっています。
SELECT DISTINCT posting_id
FROM news_posting np
INNER JOIN news_cat_match ncm ON (ncm.posting_id = np.posting_id AND ncm.category_id IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20))
WHERE np.is_active = 1
AND np.released_date < '2013-01-28'
ORDER BY np.token DESC LIMIT 50
1 つだけを指定category_id
すると、重複した結果の削除を処理する必要がないため、クエリは a を含まず、filesort
かなり高速です。EXPLAIN
ただし、複数の を含む上記のクエリを呼び出すと、実行する必要category_id
があることを示すテーブルが返さfilesort
れます。また、私のデータセットではクエリが非常に遅くなります。
テーブルのセットアップやクエリを最適化する方法はありますか?