SQL多SELECT太慢(7分钟)

时间:2013-07-20 09:04:12

标签: sql select

这个来源很好,但太慢了。 功能: 如果SC和%% 5和2013.07.11<日期< 2013年7月18日 和 一些较旧的线代表线 方法: 查找X计数行。 一个接一个地查看是否有28天的一致性

select efi_name, efi_id, count(*) as dupes, id, mlap_date
from address m
where 
mlap_date > "2013.07.11"
and mlap_date < "2013.07.18"  
and mlap_type = "SC"
and calendar_id not like "%%5"

and  concat(efi_id,irsz,ucase(city), ucase(address)) in (
    select concat(k.efi_id,k.irsz,ucase(k.city), ucase(k.address)) as dupe
    from address k
    where k.mlap_date > adddate(m.`mlap_date`,-28)
    and k.mlap_date < m.mlap_date
    and k.mlap_type = "SC"
    and k.calendar_id not like "%%5"
    and k.status = 'Befejezett'
    group by concat(k.efi_id,k.irsz,ucase(k.city), ucase(k.address))
    having (count(*) > 1)
)
group by concat(efi_id,irsz,ucase(city), ucase(address))

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

NOT LIKE加上以通配符为前缀的术语是索引使用杀手。

您还可以尝试使用IN替换inner join +内联表:优化程序是否运行NOT LIKE查询两次(请参阅解释计划)?

看起来您可能正在使用MySql,在这种情况下,您可以基于

构建哈希列
efi_id 
irsz
ucase(city)
ucase(address))

直接比较该列。这是在MySql中实现散列连接的一种方法。

答案 1 :(得分:0)

我认为您不需要子查询来执行此操作。您应该只使用外部group by和条件聚合来执行此操作。

select efi_name, efi_id,
       sum(case when mlap_date > "2013.07.11" and mlap_date < "2013.07.18" then 1 else 0 end) as dupes, 
       id, mlap_date
from address m
where mlap_type = 'SC' and calendar_id not like '%%5'
group by efi_id,irsz, ucase(city), ucase(address)
having sum(case when m.status = 'Befejezett' and
                     m.mlap_date <= '2013.07.11' and
                     k.mlap_date > adddate(date('2013.07.11'), -28)
                then 1
                else 0
           end) > 1

这会产生与查询略有不同的结果。它不是查看每个记录之前的28天,而是查看本周期间的所有记录,然后查看该期间之前的四周。尽管存在这种微妙的差异,但在一周时间之前的四周时间内仍然存在欺骗行为。