2014-12-04 90 views
0

我有一個表包含今天5m記錄。到這個數據將增加到1或20億記錄。我的任務是從這些數據中生成一個總結報告,爲此我正在使用下面的查詢。Sql查詢花費太多的時間與組通過

SELECT creation_date 
    ,caller_circle 
    ,count(id) 
FROM call_reporting 
WHERE enterprise_id = 206 
GROUP BY DATE (creation_date) 
    ,caller_circle limit 10; 

表結構看起來像這樣。

CREATE TABLE `call_reporting` (
    `ID` bigint(20) NOT NULL AUTO_INCREMENT, 
    `SESSION_ID` varchar(255) DEFAULT NULL, 
    `CALLER_NUMBER` bigint(20) NOT NULL, 
    `DIALED_NUMBER` bigint(20) NOT NULL, 
    `CALL_START_TIME` datetime DEFAULT NULL, 
    `CALL_END_TIME` datetime DEFAULT NULL, 
    `OUT_CALL_START_TIME` datetime DEFAULT NULL, 
    `OUT_CALL_END_TIME` datetime DEFAULT NULL, 
    `HUNTING_START_TIME` datetime DEFAULT NULL, 
    `IN_CALL_DURATION` bigint(20) DEFAULT NULL, 
    `OUT_CALL_DURATION` bigint(20) DEFAULT NULL, 
    `HUNTING_DURATION` bigint(20) DEFAULT NULL, 
    `ADV_ID` bigint(20) DEFAULT NULL, 
    `ENTERPRISE_ID` bigint(20) DEFAULT NULL, 
    `AGENT_ID` bigint(20) DEFAULT NULL, 
    `HUNT_TRY` int(255) DEFAULT NULL, 
    `CAMPAIGN_ID` bigint(20) DEFAULT NULL, 
    `CALL_STATUS` varchar(255) DEFAULT NULL, 
    `URL_CALLING_STATUS` varchar(255) DEFAULT NULL, 
    `REMARKS` text, 
    `REF_NO` varchar(255) DEFAULT NULL, 
    `POST_CALL_RESULT` bit(1) DEFAULT NULL, 
    `CREATION_DATE` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `AGENT_DIAL_OUT_NUMBER` bigint(20) DEFAULT NULL, 
    `DATA_SYNC` bit(1) DEFAULT NULL, 
    `CALLER_CIRCLE` varchar(50) DEFAULT NULL, 
    `STATUS_CODE` varchar(50) DEFAULT NULL, 
    `OPERATOR_NAME` varchar(50) DEFAULT NULL, 
    `OBD_RESULT_STATUS` bit(1) DEFAULT NULL, 
    `MAIL_SENT` bit(1) DEFAULT NULL, 
    `SDR_ID` varchar(255) DEFAULT NULL, 
    `KEY_PRESS` varchar(1024) DEFAULT NULL, 
    `ENTERPRISE_USER_ID` bigint(20) DEFAULT NULL, 
    `CAMAIGN_NAME` varchar(128) DEFAULT NULL, 
    `DND_NO` bit(1) DEFAULT b'0', 
    KEY `ID` (`ID`), 
    KEY `ENTERPRISE_ID` (`ENTERPRISE_ID`), 
    KEY `SDR_ID` (`SDR_ID`), 
    KEY `CALLER_NUMBER` (`CALLER_NUMBER`), 
    KEY `CREATION_DATE` (`CREATION_DATE`), 
    KEY `DIALED_NUMBER` (`DIALED_NUMBER`), 
    KEY `CALLER_CIRCLE` (`CALLER_CIRCLE`), 
    KEY `CAMAIGN_NAME` (`CAMAIGN_NAME`), 
    KEY `ADV_ID` (`ADV_ID`) 
) ENGINE=InnoDB AUTO_INCREMENT=2612658 DEFAULT CHARSET=latin1 
/*!50100 PARTITION BY HASH (MONTH(CREATION_DATE)) 
PARTITIONS 12 */ | 

此表還包含分區。但是當我運行給定的查詢需要

10 rows in set (15.11 sec) 

當我看到了查詢配置文件它提供了以下統計。

+--------------------------------+-----------+ 
| Status       | Duration | 
+--------------------------------+-----------+ 
| starting      | 0.000052 | 
| Waiting for query cache lock | 0.000017 | 
| checking query cache for query | 0.000106 | 
| checking permissions   | 0.000023 | 
| Opening tables     | 0.000051 | 
| System lock     | 0.000035 | 
| Waiting for query cache lock | 0.000015 | 
| init       | 0.000085 | 
| optimizing      | 0.000036 | 
| statistics      | 0.003924 | 
| preparing      | 0.000075 | 
| Creating tmp table    | 0.000077 | 
| executing      | 0.000014 | 
| Copying to tmp table   | 16.945653 | 
| Sorting result     | 0.000879 | 
| Sending data     | 0.001254 | 
| end       | 0.000012 | 
| removing tmp table    | 0.000017 | 
| end       | 0.000010 | 
| query end      | 0.000013 | 
| closing tables     | 0.000019 | 
| freeing items     | 0.000030 | 
| logging slow query    | 0.000008 | 
| logging slow query    | 0.000008 | 
| cleaning up     | 0.000007 | 
+--------------------------------+-----------+ 
25 rows in set (0.01 sec) 

將數據複製到臨時表中需要花費大量的時間;有什麼辦法可以縮短執行時間嗎?在我的情況下,臨時表大小是

tmp_table_size       | 16777216 | 

我也在考慮將數據加載到RAM中。但不要它的優點和缺點。因爲在我的情況下,數據量將會擴大。請給出一個方法來做到這一點。

在此先感謝。

+0

你在這張桌子上有什麼樣的索引? – 2014-12-04 17:08:26

+0

索引類型BTree,Column-ID,Enterprise_Id,Sdr_id,caller_number,Dialed_number,cAller_circle,Campaing_Name,Av_id – 2014-12-04 17:16:52

+0

基數爲,2602135,24,650533,2602135,236557,24,24,24按照上述列順序 – 2014-12-04 17:19:02

回答

0

嘗試在

(enterprise_id,CREATION_DATE,caller_circle)創建覆蓋索引

這樣,WHERE子句由ID優化,GROUP BY可以從索引也可以使用。

另外,從「count(ID)」改爲「count(*)」,引擎不必去頁面獲取ID,它只知道覆蓋索引中的一條記錄。

然後,我會建議創建一個輔助表,其中包含給定企業,日期和調用者圈子的簡單聚合彙總。那是......如果原始數據不會歷史性地改變(例如回填呼叫數據)。它發生了,它完成了,總數就是歷史日期。然後,如果需要重新校準任何內容,您可以逐步重建,例如一個月/一年,這樣您未來就不會翻閱十億條記錄。

+0

應該i刪除分區或索引或分區都會提高性能 – 2014-12-04 17:21:05

+0

@naveen,不太瞭解有關此方面的數據幫助的分區上下文。按月份劃分,然後這些年會做些什麼......您的查詢將主要基於以下日期範圍:日期範圍,企業,來電者圈子?沒有足夠的真正提供更好的答案。 – DRapp 2014-12-04 17:25:46

+0

表將只包含最近2個月的數據不超過該數據,表已被月份散列鍵分區。 – 2014-12-04 17:27:55