mer*_*lin 5 mysql group-by like
我需要从我们的 MySQL-DB 中获取一些统计信息,并想知道是否有更快的方法来做到这一点。
基本上,在按属性进行分隔之前,我需要有关任何给定月份的用户注册信息。
例如:
SELECT count(*) AS c
FROM `users`
WHERE `date_created` LIKE '2015-10%'
AND `country` = 'DE'
Run Code Online (Sandbox Code Playgroud)
这将返回 2015 年 10 月的数字。如何更改此语句以在一个语句中返回所有月份的结果?
我也有兴趣添加类似AND confirmed = 1
单独的结果。
仅使用一个 MySQL 语句就可以做到这一点吗?
需要做两件事才能让它运行得更快:
获取合适的索引
没有confirmed = 1
,你需要
INDEX(country, date_created)
Run Code Online (Sandbox Code Playgroud)
有了它,你需要
INDEX(country, confirmed, date_created)
Run Code Online (Sandbox Code Playgroud)
避免在函数中隐藏日期
LIKE '2015-10%'
不能在 上使用索引date_created
,也不能MONTH(date_created)
,所以让我们重新制定查询:
WHERE date_created >= '2015-10-01'
AND date_created < '2015-10-01' + INTERVAL 1 MONTH
AND confirmed = 1 -- add this if you want to limit to confirmed rows
Run Code Online (Sandbox Code Playgroud)
(这假设它date_created
是一个DATETIME
orTIMESTAMP
数据类型。)
所有月份
这个查询仍然可以使用我建议的两个索引,但是,它不一定会使用该date_created
部分。
SELECT LEFT(date_created, 7) AS YYYY_MM,
COUNT(*) AS ct
FROM tbl
WHERE country = 'DE'
AND confirmed = 1 -- if you want this
GROUP BY YYYY_MM;
Run Code Online (Sandbox Code Playgroud)
注意事项 country_code
定义模式(请提供SHOW CREATE TABLE
)的一个常见错误是将其定义为CHAR(2)
并默认为 utf8。这导致使用 6 个字节,而 2 个就足够了。更改为CHAR(2) CHARACTER SET ascii
。
SELECT
EXTRACT(YEAR FROM date_created) AS yr, -- for each year
EXTRACT(MONTH FROM date_created) AS mth, -- & month combination
count(*) AS c, -- count all rows
SUM(CASE WHEN confirmed = 1 THEN 1 ELSE 0 END) -- count only confirmed rows
FROM users
WHERE country = 'DE'
GROUP BY yr, mth
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3677 次 |
最近记录: |