需要帮助加速MySQL查询

时间:2012-10-25 07:58:44

标签: mysql

我需要一个查询,可以快速显示用户未上传PDF的特定模块(文章的子集)中的文章。我在下面使用的查询大约需要37秒,因为文章表中有300,000篇文章,而模块中有6,000篇文章。

SELECT * 
FROM article a 
INNER JOIN article_module_map amm ON amm.article=a.id 
WHERE amm.module = 2 AND
    a.id NOT IN ( 
        SELECT afm.article 
        FROM article_file_map afm 
        INNER JOIN article_module_map amm ON amm.article = afm.article 
        WHERE afm.organization = 4 AND 
            amm.module = 2 
    ) 

我在上面的查询中所做的是首先将文章列表截断到所选模块,然后进一步将该列表截断为不在子查询中的文章。子查询正在生成组织已为其上载PDF的文章列表。因此,最终结果是组织尚未上传PDF的文章列表。

非常感谢帮助,提前谢谢!

编辑2012/10/25

在@ fthiella的帮助下,以下查询以惊人的1.02秒运行,从37秒开始!

SELECT a.* FROM (
    SELECT article.* FROM article 
    INNER JOIN article_module_map
        ON article.id = article_module_map.article
    WHERE article_module_map.module = 2
) AS a
LEFT JOIN article_file_map
    ON a.id = article_file_map.article
    AND article_file_map.organization=4
WHERE article_file_map.id IS NULL

2 个答案:

答案 0 :(得分:1)

在优化查询时,我会用来检查以下几点:

首先:我会避免在SELECT子句中使用*,而是命名你想要的不同字段。这疯狂地增加了速度(我有一个用*花了7秒钟,并且命名场减少到0.1秒)。

第二:正如@Adder所说,为你的表添加索引。

第三:尝试使用INNER JOIN而不是WHERE amm.module = 2 AND a.id NOT IN(...)。我认为我读过(我不记得了,所以请小心)通常MySQL优化INNER JOINS,并且因为你的子查询是一个过滤器,也许使用三个INNER JOINS加上WHERE会更快检索。

答案 1 :(得分:1)

我不确定我是否能正确理解表格的逻辑和结构。这是我的问题:

SELECT
  article.id
FROM
  article
    INNER JOIN
  article_module_map
    ON article.id = article_module_map.article
    AND article_module_map.module=2
  LEFT JOIN
    article_file_map
    ON article.id = article_file_map.article
    AND article_file_map.organization=4
WHERE
  article_file_map.id IS NULL

我提取所有具有模块2的文章。然后选择那些组织4没有提供文件的文章。

我使用LEFT JOIN而不是子查询。在某些情况下,这可能会更快。

编辑感谢您的评论。我不确定它会跑得更快,但令我惊讶的是它速度要慢得多!无论如何,值得一试!

现在,出于好奇,我想尝试LEFT / INNER JOIN和子查询的所有组合,看看哪一个运行得更快,例如:

SELECT *
FROM
  (SELECT *
   FROM
     article INNER JOIN article_module_map
     ON article.id = article_module_map.article
   WHERE
     article_module_map.module=2)
  LEFT JOIN
etc.

也许删除*,我想看看WHERE子句和ON子句之间的条件有什么变化......无论如何我认为它没有多大帮助,你现在应该专注于索引。

键/外键上的索引应该已经可以了,但是如果在article_module_map.module和/或article_file_map.organization上添加索引怎么办?