0

我的查询是这样的:

SELECT date_format( created_at, '%Y-%m-%d' ) AS the_date, 
COUNT(s.id) AS total, 
(SELECT COUNT(ks.id) FROM kc_shares ks WHERE site = 'facebook' AND date_format( created_at, '%Y-%m-%d' ) = the_date ) AS total_facebook, 
(SELECT COUNT(ks.id) FROM kc_shares ks WHERE site = 'twitter' AND date_format( created_at, '%Y-%m-%d' ) = the_date ) AS total_twitter 
FROM `kc_shares` s
GROUP BY `the_date`

我想要得到的是每日分享的数量,其中包含总份额、facebook 的总份额(因此 site = 'facebook')和 twitter 的总份额。这就是为什么我需要GROUP BY.

当它有几千行时,没有问题。但是该表目前几乎有 200,000 行,并且查询非常慢,大约需要 20-30 秒,我猜还要更多。

我尝试向站点和 created_at 字段添加索引,但无济于事。

谢谢

4

3 回答 3

1

移动子选择以便加入它们,而不是为每个返回的行进行子选择。

像这样的东西(未经测试): -

SELECT date_format( created_at, '%Y-%m-%d' ) AS the_date, 
COUNT(s.id) AS total, 
Sub1.total_facebook, Sub2.total_twitter
FROM `kc_shares` s
LEFT OUTER JOIN (SELECT date_format( created_at, '%Y-%m-%d' ) AS sub_date, COUNT(ks.id) AS total_facebook FROM kc_shares ks WHERE site = 'facebook' GROUP BY sub_date ) Sub1 ON date_format( created_at, '%Y-%m-%d' ) = Sub1.sub_date
LEFT OUTER JOIN (SELECT date_format( created_at, '%Y-%m-%d' ) AS sub_date, COUNT(ks.id) AS total_twitter  FROM kc_shares ks WHERE site = 'twitter' GROUP BY sub_date ) Sub2 ON date_format( created_at, '%Y-%m-%d' ) = Sub2.sub_date
GROUP BY `the_date`

虽然找到一种方法来对非派生列(即日期/时间的日期部分)进行连接也会有所帮助。在这里可能是一个很好的例子,用于一点或非规范化,在当前存储的日期/时间之外添加一个仅用于日期的字段。

于 2013-03-18T10:10:55.067 回答
1

我认为子查询正在消耗性能。所以也许你可以做这样的事情:

SELECT 
    date_format( created_at, '%Y-%m-%d' ) AS the_date, 
    COUNT(s.id) AS total, 
    SUM(CASE WHEN s.site='facebook' THEN 1 ELSE 0 END) AS total_facebook, 
    SUM(CASE WHEN s.site='twitter' THEN 1 ELSE 0 END) AS total_twitter
FROM 
    `kc_shares` s
GROUP BY 
    `the_date

`

于 2013-03-18T10:12:48.163 回答
0

另一种方法是更改​​查询的工作方式。以下将为每一天/站点提供行,而不是将两个站点放在同一行上。

SELECT 
   date_format( created_at, '%Y-%m-%d' ) AS the_date,site, 
   count(id) 
FROM 
   kc_shares s 
where 
   (site="facebook" or site="twitter") ) 
group by  
   created_at, site

我假设 created_at 是一个日期字段。

这应该提供相同的数据(我想,我没有尝试过),但格式不同。

在 (created_at,site) 上尝试索引。

于 2013-03-18T10:20:02.520 回答