在SQL中联接大表

阿比丁凯

我有一个名为“ calls”的表,有以下几列:

a_imei_number
b_imei_number
a_phone_number
b_phone_number

call_start_time
call_end_time

如果称为x的特定电话呼叫y,则x的imei号在a_imei_number列中。如果y呼叫x,则x的imei数在列中b_imei_numbera_imei_number之间的短暂区别b_imei_number是imei的呼入和呼出。对于phone_number列也是如此。

我正在搜索在同一时间发生的特定imei呼叫(克隆的imei号码),所以我想如果我找到一个在其他人的call_start_time和call_end_time之间的call_start_time的呼叫,那么我会找到克隆的电话。因此,逻辑上,IMEI号码必须相同,电话号码也必须不同。

所以我写了

select * from calls c1 , calls c2 
where (c1.a_imei = 1234 or c1.b_imei = 1234) 
and 
c1.call_start_time between c2.call_start_time and c2.call_end_time

该表可能有500M数据。因此此查询未返回,结果可能会在1周内返回。有没有其他方法可以找到结果而不连接像这样的同一个表呢?

戈登·利诺夫

如果我理解正确,则您正在查找与拨打特定号码或同时拨打特定号码的电话。以下查询表达了这个想法:

select c2.*
from (select c.*
      from calls c
      where c.a_imei = 1234 or c.b_imei = 1234
     ) cbase join
     calls c2
     on cbase.call_start_time between c2.call_start_time and c2.call_end_time;

性能将在很大程度上取决于第一个查询的匹配数。

有时,数据库引擎很难or在某种条件下进行优化我建议在上建立索引calls(a_imei, call_start_time)并将calls(b_imei, call_start_time)查询重写为:

select c2.*
from ((select c.call_start_time
       from calls c
       where c.a_imei = 1234
      ) union all
      (select c.call_start_time
       from calls c
       where c.b_imei = 1234
      )
     ) cbase join
     calls c2
     on cbase.call_start_time between c2.call_start_time and c2.call_end_time;

对于最后的联接,第三个索引将是有用的:calls(call_start_time, call_end_time)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章