超慢的mysql查询 - 需要优化

时间:2014-08-21 19:43:24

标签: mysql

我不确定这是否是sql server优化或查询问题的问题,但是这里有。

我有一个我继承的各种新闻媒体的文章数据库。有两个表:news_articles和news_outlets。我正在尝试确定不同文章的数量,允许同一篇文章在多个出版物中发布(数据库中有很多重复文章)。

这是我的疑问:

SELECT outs.id, outs.site, COUNT(DISTINCT CONCAT(arts.body_text, outs.site)) AS Article_Count, outs.alignment
FROM news_articles arts
INNER JOIN 
news_outlets outs ON arts.outlet_id = outs.id
WHERE
arts.search_perc > 0.0
AND
arts.search_perc < 0.85
AND
outs.out_type < 3
GROUP BY outs.site, outs.alignment

注意:不幸的是,由于数据库的原始设计(我没有时间修复),每个实际的新闻媒体也有多个outlet_id(想象一个网络爬虫返回mobile.cnn.com的同一页面和www.cnn.com,你有问题;每个都有一个单独的outlet_id)。这不是我现在可以轻松解决的问题。

outs.site,outs.alignment,id和outs.out_type都有索引。所有表都是innodb。 news_outlets中有大约800条记录,news_articles中大约有6M条记录。这是使用MySQLdb从python连接到服务器(在同一工作站上)。该工作站是今年的2.7GHz i5,配备16GB内存。我没有改变my.cnf,但我修改了这个:     innodb_buffer_pool_size = 12288M

这两种方式似乎都没有多大区别。

这个查询运行了很长时间(虽然并不总是 - 当我昨晚运行一个非常相似的查询时,它看起来要快得多)。我认识到它做了很多,所以这是可以理解的。然而EXPLAIN说有两个简单的过程:一个使用where,filesort;另一个使用索引条件的地方。

每当我运行SHOW processlist时,它说查询是创建排序索引。然而,CPU使用率最高达到5%。

这是服务器优化问题吗?查询优化问题?我该如何解决?我有大约60个这样的查询要运行 - 没有完成;我倾向于在10-20分钟后杀死它们。

提前谢谢。

3 个答案:

答案 0 :(得分:0)

SELECT  outs.id, 
outs.site, 
COUNT(DISTINCT CONCAT(arts.body_text, outs.site)) AS Article_Count,     outs.alignment FROM     (SELECT *
FROM    news_articles na
WHERE   na.search_perc > 0.0
AND na.search_perc < 0.85)arts INNER JOIN ( SELECT *
    FROM news_outlets no
    WHERE outs.out_type < 3) outs ON    arts.outlet_id = outs.id GROUP BY outs.site, outs.alignment

答案 1 :(得分:0)

  

回答评论


我将假设计数需要进行大量无法优化的处理(至少在MySQL中没有)。你需要这个吗?你需要用这种方式来计算吗?因为你是通过id加入我不想出来的。每个concat的网站都会有所不同。所以至少把它更改为COUNT(DISTINCT arts.body_text)。

您不需要检查这两个字段,因为outs.site将无法在一个结果行中进行更改。你在该专栏上做了一个小组。

答案 2 :(得分:0)

试试这个 - 另一种选择,我需要在不太了解你的表格结构的情况下写下这个 SELECT outs.id, outs.site, outs.alignment, ( SELECT COUNT ( DISTINCT (arts.body_text) FROM news_articles na WHERE no.outlet_id = na.id AND na.search_perc > 0.0 AND na.search_perc < 0.85) AS Article_Count COUNT(DISTINCT CONCAT(arts.body_text, outs.site)) FROM news_outlets no WHERE outs.out_type < 3