-1

我有一个特定的左连接问题,它大大减慢了一个重要的查询。使用 PHPMyAdmin 来测试查询,它指出查询需要 3.9 秒才能返回 546 行,尽管我不得不等待 67 秒才能看到让我感到奇怪的结果。

涉及两个表:nsi(1,553 行)和 files(233,561 行)。此查询中提到的所有列都被单独索引,并且文件表中的 filejobid、category 和 isactive 上有一个复合索引。所有被比较的东西也是一个整数。

这个查询的淡化版本的目标是显示 nsi 表中的行一次,并能够确定是否有人上传了类别 20 中的文件。可以有多个文件,但应该只有一行,因此是分组。

查询:

SELECT 
    nsi.id AS id,
    f.id AS filein
FROM nsi nsi
LEFT JOIN files f
    ON f.filejobid=nsi.leadid AND f.category=20 AND f.isactive=1
WHERE nsi.isactive=1
GROUP BY nsi.id

这个数据的 67 秒加载时间对于我的应用程序来说简直是不可接受的,我不知道如何进一步优化它。我已经索引和复合索引。我应该只是寻找一个新的更迂回的解决方案吗?

感谢您的任何帮助!

4

1 回答 1

2

这是你的查询,我觉得有点可疑,因为你有一个聚合但没有聚合函数f.id。它将返回一个任意匹配的 id:

SELECT nsi.id AS id, f.id AS filein
FROM nsi LEFT JOIN
     files f
     ON f.filejobid = nsi.leadid AND f.category = 20 AND f.isactive = 1
WHERE nsi.isactive = 1
GROUP BY nsi.id;

对于这个查询,我认为最好的索引是files(filejobid), category, isactive)and nsi(isactive, filejobid, id)

但是,您可以轻松地重写查询以提高效率,因为它不需要group by(假设nsi.id是唯一的):

SELECT nsi.id AS id,
       (SELECT f.id
        FROM files f
        WHERE  f.filejobid = nsi.leadid AND f.category = 20 AND f.isactive = 1
        LIMIT 1
       ) AS filein
FROM nsi 
WHERE nsi.isactive = 1;

相同的索引适用于此。

如果您想要一个匹配文件的列表,而不仅仅是一个,请group_concat()在任一查询中使用。

于 2015-07-31T15:31:53.293 回答