mysql-多查询或单查询

vfh0ocws  于 2021-08-13  发布在  Java
关注(0)|答案(3)|浏览(307)

所以我有一个包含投票的表格。此问题的相关列为 user 以及 timestamp .
我需要抓取用户的总票数,还有他们这个月的投票数。
我知道这些问题-我不是在问这些。我同时使用这些:
本月票数/总票数:

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 = ?;

最佳做法是什么?有没有从同一个表中查询多个信息位的提示,以防止必须搜索两次?我的组合查询是我应该使用的吗?
谢谢!

jjhzyzn0

jjhzyzn01#

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

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”查询还需要对用户的所有行进行一次扫描。
“this month”查询,如果使用 BETWEEN 或者 >= 本月只扫描用户的行(我的没能做到,但没关系。)

00jrzges

00jrzges2#

在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) 看起来更简单。

2cmtqfgy

2cmtqfgy3#

我建议使用第二种解决方案,即使用带条件和的唯一查询。
理由:要生成第二个结果集,需要扫描第一个结果集的子集。所以所需的额外处理是非常小的。另一方面,运行两个单独的查询涉及到一次到服务器的往返,一次对查询规划器的查询解析,以及对表的额外扫描。
为了提高性能,您需要一个索引 (user, timestamp) .

相关问题