4

10,000 行を超える大きなテーブルがあり、近い将来 1,000,000 行に増加します。各ユーザーの各キーワードの Time 値を返すクエリを実行する必要があります。左結合を使用し、サブクエリ/キーワードが1つ必要なため、現在非常に遅いものがあります。

SELECT rawdata.user, t1.Facebook_Time, t2.Outlook_Time, t3.Excel_time
FROM
rawdata left join
(SELECT user, sec_to_time(SuM(time_to_sec(EndTime-StartTime))) as 'Facebook_Time'
FROM rawdata 
WHERE MainWindowTitle LIKE '%Facebook%'
GROUP by user)t1 on rawdata.user = t1.user left join
(SELECT user, sec_to_time(SuM(time_to_sec(EndTime-StartTime))) as 'Outlook_Time'
FROM rawdata 
WHERE MainWindowTitle LIKE '%Outlook%'
GROUP by user)t2 on rawdata.user = t2.user left join
(SELECT user, sec_to_time(SuM(time_to_sec(EndTime-StartTime))) as 'Excel_Time'
FROM rawdata 
WHERE MainWindowTitle LIKE '%Excel%'
GROUP by user)t3 on rawdata.user = t3.user

テーブルは次のようになります。

WindowTitle | StartTime | EndTime | User
------------|-----------|---------|---------
Form1       | DateTime  | DateTime| user1
Form2       | DateTime  | DateTime| user2
...         | ...       | ...     | ...
Form_n      | DateTime  | DateTime| user_n

出力は次のようになります。

User   | Keyword   | SUM(EndTime-StartTime)
-------|-----------|-----------------------
User1  | 'Facebook'|              00:34:12
User1  | 'Outlook' |              00:12:34
User1  | 'Excel'   |              00:43:13
User2  | 'Facebook'|              00:34:12
User2  | 'Outlook' |              00:12:34
User2  | 'Excel'   |              00:43:13
...    | ...       | ...  
User_n | ...       | ...

問題は、MySQL でこれを行うための最速の方法はどれかということです。

4

1 に答える 1

4

ワイルドカード検索がおそらく最も速度を落としていると思います。これらのフィールドではインデックスを実際に利用できないからです。また、サブクエリを実行せずに単純な結合を実行できる場合、それは役立つかもしれませんが、ワイルドカード検索ははるかに悪いです. とにかく、テーブルを変更して、インデックスを持つことができ、ワイルドカード検索を必要としない categoryName または categoryID を持つことはできますか? 「where categoryName = 'Outlook'」のように

テーブルのデータを最適化するには、categoryID を追加します (理想的には、これは別のテーブルを参照しますが、この例では任意の数値を使用しましょう)。

alter table rawData add column categoryID int not null

alter table rawData add index (categoryID)

次に、既存のデータの categoryID フィールドに入力します。

update rawData set categoryID=1 where name like '%Outlook%'
update rawData set categoryID=2 where name like '%Facebook%'
-- etc...

次に、同じルールに従うようにインサートを変更します。

次に、次のように SELECT クエリを作成します (ワイルドカードを categoryID に変更)。

SELECT rawdata.user, t1.Facebook_Time, t2.Outlook_Time, t3.Excel_time
FROM
rawdata left join
(SELECT user, sec_to_time(SuM(time_to_sec(EndTime-StartTime))) as 'Facebook_Time'
FROM rawdata 
WHERE categoryID = 2
GROUP by user)t1 on rawdata.user = t1.user left join
(SELECT user, sec_to_time(SuM(time_to_sec(EndTime-StartTime))) as 'Outlook_Time'
FROM rawdata 
WHERE categoryID = 1
GROUP by user)t2 on rawdata.user = t2.user left join
(SELECT user, sec_to_time(SuM(time_to_sec(EndTime-StartTime))) as 'Excel_Time'
FROM rawdata 
WHERE categoryID = 3
GROUP by user)t3 on rawdata.user = t3.user
于 2012-09-30T04:48:54.763 に答える