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 への合計共有 (したがって、サイト = 'facebook') および twitter への合計共有の指定による毎日の共有の数です。それが私が必要な理由ですGROUP BY

数千行の場合は問題ありません。しかし、テーブルには現在ほぼ 200,000 行あり、クエリは非常に遅く、約 20 ~ 30 秒かかります。

site および 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

別の方法は、クエリの動作方法を変更することです。以下は、同じ行に 2 つのサイトを配置するのではなく、各日/サイトの行を提供します。

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 に答える