繁体   English   中英

MySQL查询非常慢

[英]MySQL Query is Extremely Slow

您好,我正在寻找优化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.';

来源表的结构

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.'

Articles表包含约30万条记录,sources表包含约1000条记录,执行该查询大约需要180秒。

任何帮助将不胜感激。

在此处输入图片说明

尝试使用带有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

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

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

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

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

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

试试这个查询

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

我已经删除了多余的查询,并通过接受user_id以外的所有source_id (id为5之外)来添加了join中的news_sources_deselected

或者我们可以按照用户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

希望这可以帮助..

我通过对表进行分区来解决此问题,但我仍然愿意提出建议。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM