2013-04-10 262 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 ..