1

您好我正在寻找优化 mysql 查询的方法,基本上我正在为属于 category_id = 25 和 source_id 的用户获取文章,而不是在我存储用户已取消订阅的源 ID 的表中。

select
  a.article_id,
  a.article_title,
  a.source_id,
  a.article_publish_date,
  a.article_details,
  n.source_name
from sources n
  INNER JOIN articles a
    ON (a.source_id = n.source_id)
WHERE n.category_id = 25
    AND n.source_id NOT IN(select
                 source_id
               from news_sources_deselected
               WHERE user_id = 5)
ORDER BY a.article_publish_date DESC

文章表的架构

CREATE TABLE IF NOT EXISTS `articles` (<br>
  `article_id` int(255) NOT NULL auto_increment,<br>
  `article_title` varchar(255) NOT NULL,<br>
  `source_id` int(255) NOT NULL,<br>
  `article_publish_date` bigint(255) NOT NULL,<br>
  `article_details` text NOT NULL,<br>
  PRIMARY KEY  (`article_id`),<br>
  KEY `source_id` (`source_id`),<br>
  KEY `article_publish_date` (`article_publish_date`)<br>
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='Contains articles.';

Sources 表的结构

CREATE TABLE IF NOT EXISTS `sources` (<br>
  `source_id` int(255) NOT NULL auto_increment,<br>
  `category_id` int(255) NOT NULL,<br>
  `source_name` varchar(255) character set latin1 NOT NULL,<br>
  `user_id` int(255) NOT NULL,<br>
  PRIMARY KEY  (`source_id`),<br>
  KEY `category_id` (`category_id`),<br>
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='News Sources.'

文章表有大约 30 万条记录,来源表包含大约 1000 条记录,执行查询大约需要 180 秒。

任何帮助将不胜感激。

在此处输入图像描述

4

5 回答 5

1

尝试使用带有 IS NULL 条件的派生查询。你解释说有一个依赖子查询。忽略使用它并使用派生查询来解决您的问题。这将提高性能

select
  a.article_id,
  a.article_title,
  a.source_id,
  a.article_publish_date,
  a.article_details,
  n.source_name
from sources n
  INNER JOIN articles a
    ON (a.source_id = n.source_id)
  LEFT JOIN (SELECT *
         FROM news_sources_deselected
         WHERE user_id = 5) AS nsd
    ON nsd.source_id = n.source_id
WHERE n.category_id = 25
    AND nsd.source_id IS NULL
ORDER BY a.article_publish_date DESC
于 2013-04-10T09:16:46.650 回答
0

在查询前使用 EXPLAIN 并分析结果。

在这里您可以找到如何开始您的优化工作。

于 2013-04-10T08:51:56.790 回答
0

我发现您可以检查的问题很少。

  • 尽管使用了 InnoDB 引擎,但您没有使用关系。
  • 您正在选择没有索引的字段。
  • 您正在一次选择所有行。

你需要一次所有这些行吗?也许考虑将此查询拆分为多个分片(分页)?

于 2013-04-10T09:03:55.493 回答
0

试试这个查询

select
 a.article_id,
 a.article_title,
 a.source_id,
 a.article_publish_date,
 a.article_details,
 n.source_name
from 
 sources n
INNER JOIN 
 articles a
ON 
 n.category_id = 25 AND 
 a.source_id = n.source_id     
INNER JOIN 
 news_sources_deselected nsd
ON
 nsd.user_id <> 5 AND n.source_id = nsd.source_id
ORDER BY 
 a.article_publish_date DESC

我已经删除了额外的查询,并news_sources_deselected通过接受除 id 以外的所有内容添加到 joinsource_id中。user_id5

或者我们可以只使用用户 raheelshan 提到的加入所需的记录

select
 a.article_id,
 a.article_title,
 a.source_id,
 a.article_publish_date,
 a.article_details,
 n.source_name
from 
 (select 
   * 
 from 
   sources 
 where 
   category_id = 25) n 
INNER JOIN 
 articles a
ON 
 a.source_id = n.source_id     
INNER JOIN 
 (select 
   * 
 from 
   news_sources_deselected 
 where 
   user_id <> 5) nsd
ON
 n.source_id = nsd.source_id
ORDER BY 
 a.article_publish_date DESC

希望这可以帮助..

于 2013-04-10T09:26:52.590 回答
0

我通过分区表解决了这个问题,但我仍然愿意接受建议。

于 2013-04-17T05:37:43.393 回答