我遇到一个特定的左连接问题,大大减慢了一个重要的查询。使用PHPMyAdmin来测试查询,它声明查询花了3.9秒返回546行,但我不得不等待67秒才能看到结果让我感到奇怪。
涉及两个表格: nsi(1,553行)和文件(233,561行)。此查询中提到的所有列都单独编制索引,并且filebobid,category上存在复合索引,并且在files表中是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秒加载时间对于我的应用程序来说简直是不可接受的,我对如何进一步优化它感到茫然。我已编入索引和复合索引。我应该只是寻找一种新的更迂回的解决方案吗?
感谢您的帮助!
答案 0 :(得分: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)
和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()
。