2013-04-10 211 views
1

你好我正在寻找方法来优化mysql查询,基本上我正在为属于category_id = 25和source_id的用户提取文章,而不是在存储源用户ID的表中退订。MySQL查询速度非常慢

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

在文章表有大约0.3万条记录和源表包含1000条左右的记录,查询大约需要180秒来执行。

任何帮助将不胜感激。

enter image description here

+0

按要求迁移。 – Iain 2013-04-10 09:11:29

+0

您使用的是哪个版本的mysql? 5.6中有一些针对子查询的查询规划器改进。 – pQd 2013-04-10 09:41:46

回答

0

我的分区表修复问题,但我仍然开放建议。

0

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

Here你可以找到如何开始你的优化工作。

+0

更新了我的问题与解释结果,谢谢 – TilalHusain 2013-04-10 08:59:45

0

我看到几个问题,你可以检查。

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

您是否需要同时使用所有这些行?也许考虑把这个查询分割成多个分片(分页)?

+0

什么选择领域没有索引手段? – TilalHusain 2013-04-10 09:05:12

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 
+0

对不起,这种方法没有改进。 – TilalHusain 2013-04-10 12:04:49

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接受所有source_iduser_id以外id为5加入。

或者我们可以去只使用需要记录加入成为提及

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 

希望这有助于用户raheelshan ..