2

365 暦年の日付のデカルト積であるテーブル t_date_interval_30 と、30 分間隔で増分される時間フィールドがあります。これをフレームワークとして使用して、通話データをハングアップします。

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 があります。コール データは、開始されたコール セッションごとに 1 行に要約されます。このソースは、コール セッションごとに複数の行を持つことができます。つまり、コールは無応答を 1 つのターゲットから別のターゲットにロールし、コールの各レグは新しいレコード行を増やします。

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`

インデックスを実際に扱ったことはありません (ただし、DATE 値と 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 日間のレポートを作成するのに 1 時間半かかります。それを解消する方法を見つける必要があります。

4

1 に答える 1

0

まず、90 日分のデータに 2 日の 45 倍の労力が必要だとは思わないでください。クエリは通話詳細テーブルのフル スキャンを実行しており、これが多くの労力を占めている可能性があります。MySQL は、等結合を介して日付からからへの条件を伝播できdiますcd。この場合にそうなるかどうかはわかりません(2番目の条件のため)。

次に、ビューを使用しています。そのため、実際にパフォーマンスを向上させることができなくなる可能性があります。試すことはできますが、ビューなしでクエリを作成するようにしてください。

私の次の質問は、これを実行するのにどれくらいの時間がかかるかです:

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テーブルに結合できます。これは単なるアイデアです。実際のパフォーマンスの問題はビューにあると思います。

于 2013-08-21T22:35:36.447 に答える