使用lot of count(行)和(行+行2)优化MySQL语句

使用lot of count(行)和(行+行2)优化MySQL语句,sql,mysql,optimization,Sql,Mysql,Optimization,我需要在一个表上使用InnoDB存储引擎,该表在任何给定时间都有大约1mil的记录。它以非常快的速度插入记录,然后在几天内,也许一周内删除。ping表大约有一百万行,而website表只有大约10000行 我的声明如下: select url from website ws, ping pi where ws.idproxy = pi.idproxy and pi.entrytime > curdate() - 3 and contentping+tcpping is not null

我需要在一个表上使用InnoDB存储引擎,该表在任何给定时间都有大约1mil的记录。它以非常快的速度插入记录,然后在几天内,也许一周内删除。ping表大约有一百万行,而website表只有大约10000行

我的声明如下:

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;

我在entrytime上添加了一个索引,但没有骰子。有谁能给我一个关于我应该考虑的问题的基本优化。结果集只有200行,因此我不会在那里被杀死。

如果没有关系的模式,我将不得不进行一些猜测

如果要生成WHERE a.attrname=b.attrname子句,则需要一个连接

使用COUNT*是多余的,有时比COUNTsome_-specific_属性效率更低。主键是一个很好的候选者

为什么要测试contentping+tcping不为NULL,要求进行看似不必要的计算,而不是单独测试属性是否为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和ORDERBY子句中执行大量相同的计算可能会降低性能。您可以将它们放在SELECT子句中,或者创建一个将这些计算作为属性的视图,并使用该视图访问值。

请编辑描述以显示所查询关系的schema create TABLE语句。请编辑描述以显示RDBMS查询解释程序在此查询中的输出。我将在回到家中的PC时执行此操作。现在我可以告诉大家:两个表中每个表上只有一个主键,在这两种情况下都是INT。唯一的索引是在那些主键上。我想知道我是否应该以某种方式创建更多的索引,因为我创建的简单索引没有任何作用。谢谢,我会在有机会的时候单独尝试这些索引,看看它们是如何工作的。