MySQL查询优化联接

时间:2019-03-25 05:23:59

标签: php mysql

我有两个表,我需要对它们执行左外部联接以获取所需的结果集。我现在有查询,但处理时间太长。有什么建议吗?

查询:

SELECT Date_format(a.call_date, '%Y-%m-%d') Call_Date,
   Date_format(a.call_date, '%H:%i:%s') Call_Time,
   a.lead_id,
   customer_number,
   status,
   a.call_type,
   agent,
   skill,
   campaign,
   disposition,
   hangup,
   a.uniqueid,
   time_to_answer,
   talk_time,
   hold_sec,
   wrapup_sec,
   Date_format(start_time, '%H:%i:%s')  Start_Time,
   Date_format(end_time, '%H:%i:%s')    End_Time,
   Ifnull(a.transfered, b.transfered)   AS transfer,
   comments,
   location,
   duration,
   handling_time,
   number_dialed                        AS DID
FROM   cdr_temp a
   LEFT OUTER JOIN (SELECT USER,
                           Substring(number_dialed, 18, 11) AS transfered,
                           uniqueid
                    FROM   transfertable)
                   b
                ON a.uniqueid = b.uniqueid
WHERE  a.call_date BETWEEN '2019-01-01 00:00:00' AND '2019-03-23 00:00:00'
GROUP  BY a.lead_id,
      b.uniqueid

表:cdr_temp cdr_temp

可转让 transfertable

索引:

uniqueid and call_date for transfertable
uniqueid and lead_id for cdr_temp

解释查询

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra   
1   SIMPLE  a   ALL     NULL    NULL    NULL    NULL    1333    Using where; Using temporary; Using filesort
1   SIMPLE  transfertable   ref     uniqueid    uniqueid    22  test.a.uniqueid     1   

PS:我需要在GROUP BY上连接技能和编号。我已经尝试过使用GROUP_CONCAT,但是它不起作用,我也不知道为什么。

1 个答案:

答案 0 :(得分:0)

我在transfertable上看不到子查询的重点。但是,仔细查看该子查询,我可以看到您正在那里调用SUBSTRING。这几乎肯定意味着MySQL将无法使用任何索引来改善连接。这里的一种方法是创建一个临时表,其中包含number_dialed的子字符串作为真诚的列。

CREATE TEMPORARY TABLE transfertable_temp (
    INDEX idx (uniqueid, transfered)
)
SELECT uniqueid, SUBSTRING(number_dialed, 18, 11) AS transfered
FROM transfertable;

加入该临时表(代替实例化视图(MySQL尚不支持))应提高连接的性能,如果MySQL选择使用它的话。请注意,我还在索引中包括了子字符串号,以覆盖正在使用的其他列。

这是您更新的查询:

SELECT
    DATE_FORMAT(a.call_date, '%Y-%m-%d') Call_Date,
    DATE_FORMAT(a.call_date, '%H:%i:%s') Call_Time,
    a.lead_id,
    customer_number,
    status,
    a.call_type,
    agent,
    skill,
    campaign,
    disposition,
    hangup,
    a.uniqueid,
    time_to_answer,
    talk_time,
    hold_sec,
    wrapup_sec,
    Date_format(start_time, '%H:%i:%s') Start_Time,
    Date_format(end_time, '%H:%i:%s') End_Time,
    IFNULL(a.transfered, b.transfered) transfer,
    comments,
    location,
    duration,
    handling_time,
    b.number_dialed DID
 FROM cdr_temp a
 LEFT JOIN transfertable_temp b
    ON a.uniqueid = b.uniqueid
WHERE
    a.call_date BETWEEN '2019-01-01 00:00:00' AND '2019-03-23 00:00:00';

注意:在当前查询中使用GROUP BY是没有意义的,尤其是因为您甚至没有调用任何聚合函数。如果您认为需要汇总,请编辑问题并告诉我们原因。