2013-08-21 24 views
2

我有一個表t_date_interval_30是365日曆年的日期的笛卡爾乘積,並以30分鐘的時間間隔遞增的時間字段。我用這個框架來掛斷呼叫數據。長時間運行MYSQL查詢,框架表和視圖與分組

t_date_interval_30 
DATE, DAYNAME, INTERVAL 
'2013-01-01', 'Tuesday', '00:00:00' 
'2013-01-01', 'Tuesday', '00:30:00' 
'2013-01-01', 'Tuesday', '01:00:00' 
'2013-01-01', 'Tuesday', '01:30:00' 
'2013-01-01', 'Tuesday', '02:00:00' 
'2013-01-01', 'Tuesday', '02:30:00' 
ETC... 

接下來我有一個視圖v_call_details是呼叫數據的摘要視圖。呼叫數據彙總爲每個呼叫會話啓動一行 - 每個呼叫會話的來源可以有多個行;即呼叫滾動無響鈴從一個目標到另一個目標的應答,呼叫的每一段增加一個新的記錄行。

v_call_details 
CLIENT, CSQ, SESS_ID, DATE, CALL_START, CONT_DISP, MET_SLA 
'Acme','ACME_CSQ','123-123456789-01','2013-01-01','2013-01-01 00:12:34','ABANDONED',TRUE 
'Acme','ACME_CSQ','123-123456998-01','2013-01-01','2013-01-01 00:45:02','HANDLED',TRUE 
'Acme','ACME_CSQ','123-123457291-01','2013-01-02','2013-01-02 13:31:58','HANDLED',FALSE 
ETC... 

所以,當我運行下面的查詢它需要永遠。

SELECT 
cd.`client`, 
cd.`csq`, 
di.`date`, 
di.`dayname`, 
di.`interval`, 
count(cd.`sess_id`) AS `calls`, 
(count(cd.`sess_id`) - sum(IF(cd.`cont_disp` = 'ABANDONED' 
     AND cd.`met_sla` > 0, 
    1, 
    0))) AS `presented` 
FROM 
t_date_interval_30 di 
    LEFT JOIN 
v_call_details cd ON (di.`date` = cd.`date` 
    AND di.`interval` = SEC_TO_TIME((TIME_TO_SEC(cd.`call_start`) DIV 1800) * 1800)) 
WHERE 
di.`date` BETWEEN '2013-05-01' AND '2013-05-02' 
GROUP BY cd.`csq`, di.`date`, di.`interval` 

我從來沒有真正使用索引的工作(雖然我已經嘗試添加幾把日期值和CALL_START值)。當我運行EXPLAIN EXTENDED時,會得到下面的結果。

id, select_type, table,      type, possible_keys, key, key_len, ref, rows, filtered, Extra 
1, PRIMARY,  di,       range, i_date,   i_date, 3,   ,  96,  100.00,  Using where; Using temporary; Using filesort 
1, PRIMARY,  <derived2>,     ALL, ,    ,  ,   ,  153419, 100.00,  , 
2, DERIVED,  t_cisco_csq_agent_details, ALL  ,    ,  ,   ,  161925, 100.00,  Using temporary; Using filesort 
2, DERIVED,  t_lkp_clients,    ALL  ,    ,  ,   ,  56,  100.00,  , 

任何意見將不勝感激。現在,如果我運行查詢,返回值爲2天的數據需要大約70秒。按照這個速度,做一個90天的報告需要一個半小時的時間......我需要找到一種方法來降低這個數據。

回答

0

首先,不要假設90天的數據將需要45天的2天的努力。您的查詢正在對通話詳細信息表進行全面掃描,這可能會佔用很多努力。 MySQL可以通過equijoin將條件從di傳播到cd。我不確定是否在這種情況下(因爲第二種情況)。

其次,您正在使用視圖。這可能會導致實際上無法提高性能。你可以嘗試,但你應該嘗試寫沒有視圖的查詢。

我的下一個問題是如何長時間這需要運行:

select cd.csq, cd.`date`, 
     SEC_TO_TIME((TIME_TO_SEC(cd.`call_start`) DIV 1800) * 1800)) as interval, 
     count(*) 
from v_call_details cd 
WHERE cd.`date` BETWEEN '2013-05-01' AND '2013-05-02'; 

如果這需要一個合理的時間量,然後對其進行測試90天。如果有效,那麼你可以先進行聚合,然後回到di表。這只是一個想法。我懷疑真正的表現問題是在視圖中。