【问题标题】:Optimizing MySQL statement with lot of count(row) an sum(row+row2)使用大量计数(行)和总和(行+行2)优化MySQL语句
【发布时间】:2010-03-22 03:45:54
【问题描述】:

我需要在任何给定时间在包含大约 100 万条记录的表上使用 InnoDB 存储引擎。它以非常快的速度将记录插入其中,然后在几天甚至一周内删除这些记录。 ping 表大约有一百万行,而 website 表只有大约 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 行,所以我不会在那里被杀。

【问题讨论】:

  • 请编辑描述以显示正在查询的关系的架构(CREATE TABLE 语句)。
  • 请编辑描述以显示 RDBMS 的查询解释器对此查询的输出。
  • 当我回到我的家用电脑时,我会这样做。现在我可以告诉这一点:两个表中的每一个上只有一个主键,并且在这两种情况下它都是一个 INT。唯一的索引在这些主键上。我想知道是否应该以某种方式创建更多索引,因为我创建的简单索引没有做任何事情。

标签: sql mysql optimization


【解决方案1】:

在没有关系模式的情况下,我将不得不做出一些猜测。

  • 如果您要创建 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 子句中,或者创建一个将这些计算作为属性的视图,并使用该视图来访问这些值。

【讨论】:

  • 谢谢,有机会我会单独尝试一下,看看它们是如何工作的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-10
相关资源
最近更新 更多