0

私の目標は、primary_category_idarticlesテーブル)または任意のセカンダリカテゴリ(articles_secondary_categories結合テーブル)が指定された値である記事を選択することです。このクエリ例では、カテゴリ1です。他の種類の結合を使用してみましたが、ここでの注意点は、記事に2次カテゴリがない可能性があることです。

SELECT DISTINCT articles.* 
FROM articles
LEFT JOIN articles_secondary_categories AS categories 
    ON categories.article_id = articles.id
WHERE 
(
    primary_category_id = 1
    OR
    categories.category_id = 1
)
    AND articles.state = "published"
    AND edition_id = 1

ORDER BY publish_at DESC
LIMIT 10;

これまたは代替案を最適化するための助けは大歓迎です。4karticlesおよび7k articles_secondary_categories(カテゴリではない)のDBでは、このクエリの実行に5秒かかります。

4

2 に答える 2

0

二次カテゴリのクエリを逆にすることができます。

(SELECT articles.* 
FROM articles
WHERE primary_category_id = 1)
UNION DISTINCT
(SELECT articles.*
FROM articles_secondary_categories AS categories 
JOIN articles ON (categories.article_id = articles.id)
WHERE categories.category_id = 1
GROUP BY articles_id)
ORDER BY publish_at DESC
LIMIT 10;

それはあなたにまともな速度のブーストを与えるはずです-ちょうどあなたがcategories.articles_idにインデックスを付けることを確認してください

于 2012-06-20T01:02:54.060 に答える
0

ORwhere句での使用は避けてください。ORオプティマイザは通常、述語でインデックスを使用しません。

categories.category_id = 1を結合条件に移動してみてください。

SELECT articles.* 
FROM articles
LEFT JOIN articles_secondary_categories AS categories 
    ON categories.article_id = articles.id and categories.category_id = 1
WHERE 1 in (ifnull(categories.category_id, primary_category_id), primary_category_id)
AND articles.state = "published"
AND edition_id = 1
ORDER BY publish_at DESC
LIMIT 10;

このクエリの鍵は1 in (ifnull(categories.category_id, primary_category_id), primary_category_id)、「カテゴリに参加した場合は、リストでそれを使用します。それ以外の場合は、primary_category_idを使用し、すべての場合でprimary_category_idを使用します。

于 2012-06-20T01:03:29.080 に答える