SELECT COUNT(*) AS total
FROM (
SELECT DISTINCT User_ID
FROM UserClicks
WHERE Date BETWEEN DATE_SUB(:startDate, INTERVAL 1 MONTH) AND :startDate
) u1
WHERE EXISTS
(
SELECT NULL
FROM UserClicks u2
WHERE u2.User_ID = u1.User_ID
AND u2.Date BETWEEN :startDate AND :endDate
)
上(User_ID, Date)
创建一个综合指数:
CREATE INDEX ix_userclicks_user_date ON UserClicks (User_ID, Date)
如果你有
SELECT COUNT(DISTINCT UserClicks.User_ID) AS total
FROM UserClicks
WHERE (UserClicks.Date BETWEEN :startDate AND :endDate)
AND (UserClicks.Date BETWEEN DATE_SUB(:startDate, INTERVAL 1 MONTH) AND :startDate)
如果日期列上添加一个索引也可能有助于很少用户,但很多点击,并有一个表Users
,您可以使用Users
表代替DISTINCT
:
SELECT COUNT(*)
FROM Users u
WHERE EXISTS
(
SELECT NULL
FROM UserClicks uc1
WHERE uc1.UserId = u.Id
AND uc1.Date BETWEEN DATE_SUB(:startDate, INTERVAL 1 MONTH) AND :startDate
)
AND EXISTS
(
SELECT NULL
FROM UserClicks uc2
WHERE uc2.UserId = u.Id
AND u2.Date BETWEEN :startDate AND :endDate
)
您的UserClicks.User_ID字段是否不唯一且已建立索引?这应该使你摆脱查询的两个DISTINCT部分。无论如何,我认为@Parrots的答案如下。 – JMD 2010-01-13 18:46:02
@andrew:是否真的有你想要做的事情,在开始日期前一个月以及开始日期和结束日期之间点击了哪些人? (请参见下面的Quassnoi注释) – Hogan 2010-01-13 19:01:17