高效的MySQL表设置和查询

高效的MySQL表设置和查询,mysql,performance,dataset,query-optimization,Mysql,Performance,Dataset,Query Optimization,假设我有以下数据库设置(我实际拥有的简化版本): 我的任务如下。我必须得到一个50条最新的新闻帖子的列表(以一定的偏移量),这些帖子是活跃的,在今天的日期之前,并且在请求中指定的20个左右的类别中的一个。在选择要返回的50条新闻帖子之前,我必须按令牌按降序对相应的新闻帖子进行排序。我的查询当前类似于以下内容: SELECT DISTINCT posting_id FROM news_posting np INNER JOIN news_cat_match ncm ON (ncm.posting_

假设我有以下数据库设置(我实际拥有的简化版本):

我的任务如下。我必须得到一个50条最新的新闻帖子的列表(以一定的偏移量),这些帖子是活跃的,在今天的日期之前,并且在请求中指定的20个左右的类别中的一个。在选择要返回的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
选择不同的过帐\u id
从新闻发布np
内部连接新闻匹配ncm ON(ncm.posting\u id=np.posting\u id和ncm.category\u id在(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)中)
其中np.is_active=1
和np.发布日期<'2013-01-28'
按np.token DESC LIMIT 50订购
仅使用一个指定的
category\u id
,查询不涉及
filesort
,而且速度相当快,因为它不必处理重复结果的删除。但是,对具有多个
category\u id
的上述查询调用
EXPLAIN
,将返回一个表,该表表示有
filesort
要执行。而且,在我的数据集上,查询速度非常慢


有什么方法可以优化表设置和/或查询吗?

我可以通过如下方式重写上面的查询,使其比使用单值类别列表版本运行得更快:

SELECT posting_id
FROM news_posting np
WHERE np.is_active = 1
AND np.released_date < '2013-01-28'
AND EXISTS (
    SELECT ncm.posting_id
    FROM news_cat_match ncm 
    WHERE 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)
    LIMIT 1
)
ORDER BY np.token DESC LIMIT 50
有人有进一步的建议吗

SELECT posting_id
FROM news_posting np
WHERE np.is_active = 1
AND np.released_date < '2013-01-28'
AND EXISTS (
    SELECT ncm.posting_id
    FROM news_cat_match ncm 
    WHERE 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)
    LIMIT 1
)
ORDER BY np.token DESC LIMIT 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 = 1)
WHERE np.is_active = 1
AND np.released_date < '2013-01-28'
ORDER BY np.token DESC LIMIT 50