MySQL-多个查询或单个查询

问题描述 投票:0回答:3

所以我有一张包含票数的表。此问题的相关列为usertimestamp

我需要获取用户的total投票数,以及他们的投票本月

我知道这些查询-我不是要这些。我同时使用这些:

[本月投票/总投票数:

SELECT COUNT( 0 ) FROM votes WHERE ( timestamp BETWEEN DATE_FORMAT( NOW( ) ,'%Y-%m-01' ) AND NOW( ) ) AND user = ?;

SELECT COUNT( 0 ) FROM votes WHERE user = ?;

目前,我的数据库还不够大(甚至没有足够的查询能力),这是性能问题所在。但是,这很快就会改变。我应该分开查询还是应该:

SELECT COUNT( 0 ) AS totalVotes,
       SUM( IF( timestamp BETWEEN DATE_FORMAT( NOW( ) ,'%Y-%m-01' )
                              AND NOW( ), 1, 0 ) ) AS votesThisMonth
    FROM votes WHERE user = ?;

最佳做法是什么?有什么技巧可以查询同一张表中的多条信息,从而避免两次搜索?我的组合查询甚至是我应该正在使用的内容吗?

谢谢!

mysql sql performance query-performance
3个回答
1
投票

在MySQL中,我建议:

SELECT COUNT(*) AS totalVotes,
       SUM(EXTRACT(YEAR_MONTH FROM timestamp) = EXTRACT(YEAR_MONTH FROM NOW())) AS votesThisMonth
FROM votes
WHERE user = ?;

上述替代方法是:

 SUM(timestamp >= CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAY)

除非您确实需要,否则我强烈建议您不要使用字符串作为日期。有多种从当前日期获取值的方法,这些方法不涉及将日期/时间值隐式或显式转换为字符串。

此外,IF()是多余的。 MySQL允许您只添加布尔值。标准SQL都不是,因此您最好使用更简洁的版本。

COUNT(0)对我很讨厌。尽管有效,但COUNT(*)COUNT(1)似乎更简单。


2
投票

我建议第二种解决方案,该解决方案使用具有条件和的唯一查询。

Rationale:要生成第二个结果集,您需要扫描第一个结果集的subset。因此,无论如何,所需的额外处理都很少。另一方面,运行两个单独的查询涉及到服务器的一次往返,为查询计划程序进行的另一次查询解析以及对表的另一次扫描。

为了提高性能,您需要在(user, timestamp)上建立索引。


1
投票

略有不同,不一定比其他建议快:

SELECT COUNT(*) AS total,
       SUM(LEFT(timestamp, 7) = LEFT(NOW(), 7)) AS this_month
    FROM tbl
    WHERE user_id = ?

并且有

INDEX(user_id, timestamp) -- in this order.  ("Covering")

返回1对2查询的问题:

  • 我的组合查询对用户的所有行进行了一次扫描。
  • 'total'查询还需要对用户的所有行进行一次扫描。
  • “本月”查询,如果使用BETWEEN>=,则仅扫描该月用户的行。 (我的失败了,但是没关系。)
© www.soinside.com 2019 - 2024. All rights reserved.