我需要在一张桌子上使用InnoDB存储引擎,在任何给定时间内都有大约1mil左右的记录。它以非常快的速度插入记录,然后在几天内,也就是一周内删除。 ping表有大约一百万行,而网站表只有大约10,000行。
我的陈述是:
select url
from website ws, ping pi
where ws.idproxy = pi.idproxy and pi.entrytime > curdate() - 3 and contentping+tcpping is not null
group by url
having sum(contentping+tcpping)/(count(*)-count(errortype)) < 500 and count(*) > 3 and
count(errortype)/count(*) < .15
order by sum(contentping+tcpping)/(count(*)-count(errortype)) asc;
我在入场时添加了一个索引,但没有骰子。任何人都可以告诉我,我应该考虑什么来进行此查询的基本优化。结果集只有200行,所以我不会在那里被杀。
答案 0 :(得分:2)
如果没有关系图式,我将不得不做出一些猜测。
如果您正在制作WHERE a.attrname = b.attrname
条款,则需要JOIN
代替。
使用COUNT(*)
是多余的,有时效率低于COUNT(some_specific_attribute)
。主键是一个很好的候选人。
为什么要测试contentping+tcpping IS NOT NULL
,要求进行不必要的计算,而不仅仅测试属性是否为空?
这是我改进的尝试:
SELECT url
FROM website AS ws
JOIN ping AS pi
ON ws.idproxy = pi.idproxy
WHERE
pi.entrytime > CURDATE() - 3
AND pi.contentping IS NOT NULL
AND pi.tcpping IS NOT NULL
GROUP BY url
HAVING
SUM(pi.contentping + pi.tcpping) / (COUNT(pi.idproxy) - COUNT(pi.errortype)) < 500
AND COUNT(pi.idproxy) > 3
AND COUNT(pi.errortype) / COUNT(pi.idproxy) < 0.15
ORDER BY
SUM(pi.contentping + pi.tcpping) / (COUNT(pi.idproxy) - COUNT(pi.errortype)) ASC;
在HAVING和ORDER BY子句中执行大量相同的计算可能会降低您的成本。您可以将它们放在SELECT子句中,也可以创建一个将这些计算作为属性的视图,并使用该视图来访问值。