SQL多重选择太慢(7分钟)

SQL多重选择太慢(7分钟),sql,select,Sql,Select,这个来源是好的,但是太慢了。 功能: 如果SC和%%5以及2013.07.11

这个来源是好的,但是太慢了。 功能: 如果SC和%%5以及2013.07.11<日期<2013.07.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))
谢谢你的帮助

不喜欢加上通配符前缀的术语是索引使用的杀手

您还可以尝试用内部联接替换IN+内联表:优化器是否两次运行NOT-LIKE查询查看您的解释计划

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

efi_id 
irsz
ucase(city)
ucase(address))

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

我认为您不需要子查询来实现这一点。您应该能够只使用外部GROUPBY和条件聚合来完成这项工作

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天,而是查看一周内的所有记录,然后查看该周期之前的四周。尽管存在这种细微的差异,但它仍然在一周之前的四周内识别重复项。

将CONCAT替换为逐个匹配,否则它比较字符串太慢。正如davek所说,我认为将WHERE in子句更改为内部连接可以解决问题。为什么要使用双%通配符?你的意思是用_;来代替吗?