将JOIN添加到WHERE时,MySQL查询非常慢

时间:2017-06-06 17:22:48

标签: mysql

以下查询快速运行,除非我添加了' areacode.hours = 2'。现在花费不到一分钟而不是一秒钟。

1   SIMPLE  lead    index   campaign_id,datetime    phone   13  NULL    181181  Using where
1   SIMPLE  campaign    eq_ref  PRIMARY PRIMARY 4   data3_db.lead.campaign_id   1   Using where
1   SIMPLE  areacode    ref code,hours  code    11  func    1   Using index condition; Using where
1   SIMPLE  dnt ref phone   phone   12  data3_db.lead.phone 1   Using where; Using index; Not exists

EXPLAIN的结果

$(document).on('change', '.task', function(){
      var o = $(this);    
      var id = $(this).attr('id');
          $.ajax({
            url: '/task/'+id,
            method: 'POST',
            data: {'_method' : 'PUT'},
            dataType: 'json',
            success:function(json){

              if(json.isSent){
                alert('Task Updated Successfully!');
                o.closest('li').fadeOut(500);
              }

            }
          });
}

1 个答案:

答案 0 :(得分:0)

联接完成后,您的where子句限制正在执行。这将导致左连接的行为类似于INNER连接。我建议将左连接右侧的那些表的限制移动到连接本身;所以在联接发生之前应用限制。 (或作为其一部分)

如果您在某个字段上检查Null,则会出现例外情况;这可以保留在where子句中。但是如果将它放在where子句中,则无法区分表中为null的dnt.ids和作为左连接的一部分的null。但是,鉴于这是一个" ID"字段我假设它不能为空并将其留在有意义的地方。

有时编译器可能会尝试在连接后应用过滤器,当您有数千条记录* 4个表时,您记录的增长可能很大;通过在限制之前/之后移动限制,引擎可以在过滤掉记录之前减少它必须构建的临时数据集。在内连接上,这并不重要,但在外连接上它不仅会影响性能;但是期望的结果。

SELECT lead.id, first, last, lead.phone, valid_phone, mobile_phone 
FROM lead 
LEFT JOIN dnt 
  ON dnt.phone = lead.phone
LEFT JOIN areacode 
  ON areacode.code = LEFT(lead.phone, 3)
 AND areacode.hours = 2
LEFT JOIN campaign 
  ON campaign.id = lead.campaign_id
 AND campaign.lft BETWEEN 0 AND 1000 
WHERE lead.datetime BETWEEN '2017-06-01 00:00:00' AND '2017-06-01 23:59:59' 
  AND dnt.id IS NULL 
GROUP BY lead.phone
ORDER BY lead.phone DESC
LIMIT 1,1000

如果仍然没有产生预期的结果和时间,那么我会查看所需的索引。