我正在运营一个网站,允许用户抓取和分析他们的Instagram竞争对手/个人账户,以监控他们的增长,看看事情进展如何,以及他们是否在实现增长目标。
对于网站的这一特定部分,我的一个MySQL查询的运行速度非常慢(每次4-6秒)。
我有两个表:- myaccounts (存储每个用户正在跟踪的所有帐户)- accounts (存储所有原始数据。每个帐号每2小时扫描一次,并在此处添加一条新记录)
下面是运行速度非常慢的查询:
SELECT M.type, M.status, M.id as masterid, A.*
FROM myaccounts as M
INNER JOIN accounts as A on M.accountid = A.userid
WHERE A.id = (
SELECT MAX(id)
FROM accounts
WHERE userid = M.accountid)
AND M.userid = ?
AND M.status = 'active'使用EXPLAIN可以显示子查询实际上遍历了表中的每一行(到目前为止大约180k )。
我使用MAX(id)的原因是我想在主页上显示账户的最新数据,并为用户提供访问另一个页面上的所有原始数据的选项。
有没有什么方法可以加快速度呢?MAX()上的某种索引?
谢谢!:)
标记
发布于 2019-09-02 17:09:02
不幸的是,您不能在字段的MAX()上创建索引,因为它是一个必须在运行时计算的值。唯一可以做到这一点的方法是维护一个存储最大值的新字段,并对其建立索引。但是,您需要确保该字段在每次运行可能更改其值的查询时都会更新。这将解决您的性能问题,但通常不建议像这样复制数据,因为总是存在新字段与其余数据不同步的风险。
与其这样做,我建议去除子查询,而使用ORDER BY按accounts.id对完整结果进行排序。然后,在查询的末尾使用LIMIT 1来选择顶部的结果。更具体地说,查询应该是这样的:
SELECT M.type, M.status, M.id as masterid, A.*
FROM myaccounts as M
INNER JOIN accounts as A on M.accountid = A.userid
WHERE M.userid = ?
AND M.status = 'active'
ORDER BY A.id DESC
LIMIT 1发布于 2019-09-02 17:22:23
您可以使用以下查询:
SELECT M.type, M.status, M.id as masterid, A.*
FROM myaccounts as M
INNER JOIN
(
SELECT MAX(id), userid FROM accounts GROUP BY userid
)
AS A
on M.accountid = A.userid
WHERE
M.userid = ?
AND M.status = 'active'发布于 2019-09-02 17:37:36
通过引入链接表lnk,您可以为每个userid提供max(Id)的“映射”。不会为每条记录(重新)生成此表。
SELECT M.type, M.status, M.id as masterid, A.*
FROM myaccounts as M
INNER JOIN
( SELECT userid uid, MAX(id) mid FROM accounts GROUP BY userid ) lnk
ON uid=accountid
INNER JOIN accounts ON id=mid AND userid=accountid
WHERE
M.userid = ?
M.status = 'active'https://stackoverflow.com/questions/57753904
复制相似问题