不是在sql花了太长时间

时间:2013-05-25 07:33:06

标签: mysql sql

我正在尝试从我的数据库中获取结果,我有以下查询:

  SELECT dubaifirstuser.mobile, dubaifirstuser.email, CONCAT( user.fname,  '', user.lname ) AS Name, bank_master.bank_name, bank_master.image, user.createdon
  FROM dubaifirstuser, user, bank_master
  WHERE dubaifirstuser.mobile = user.mobile
  AND bank_master.bank_id = user.bank_id
  AND user.bank_id IN ( 16, 18 )
  AND user.createdon <= '2012-05-31'
  AND dubaifirstuser.mobile NOT IN (SELECT mobile FROM renew_user
  );

但是执行时需要永远,条件

 AND dubaifirstuser.mobile NOT IN (SELECT mobile FROM renew_user
  );

基本上花了这么多时间查询的剩余时间在几秒钟内执行,因为我在表dubaifirstuserrenew_user中有数千条记录,我已经尝试了NOT EXISTS NOT IN仍然执行时间是永久的,两个表中都没有空记录。 请帮助您更快或更少的执行时间来获取记录?

2 个答案:

答案 0 :(得分:1)

使用OUTER JOIN而不是NOT IN子查询。

  SELECT 
  dubaifirstuser.mobile, 
  dubaifirstuser.email, 
  CONCAT( user.fname,  '', user.lname ) AS Name, 
  bank_master.bank_name,   
  bank_master.image, 
  user.createdon
  FROM dubaifirstuser
  JOIN user ON dubaifirstuser.mobile = user.mobile
  JOIN bank_master ON bank_master.bank_id = user.bank_id
  LEFT JOIN renew_user ON renew_user.mobile = dubaifirstuser.mobile
  WHERE 
  renew_user.mobile IS NULL
  AND user.bank_id IN ( 16, 18 )
  AND user.createdon <= '2012-05-31';

确保用户表上有复合索引(bank_id,createdon,mobile)

答案 1 :(得分:1)

在MySQL中,not in的替代方案表现更好,就是使用not exists。您的查询是:

dubaifirstuser.mobile NOT IN (SELECT mobile FROM renew_user)

相反:

not exists (select 1 from renew_user ru where ru.mobile = dubaifirstuser.mobile)

通过在renew_user(mobile)上建立索引,可以提高效果。在第一个查询中,它会对正在评估的每一行扫描renew_user。一遍又一遍。

顺便说一句,这是旧版MySQL的性能问题。我相信自5.6版本发布以来它一直在修复。