2013-07-20 52 views
0

此來源雖好,但速度太慢。 功能: 選擇所有行,如果SC和%% 5和2013年7月11日<日期< 2013年7月18日 和 一些舊線代表線 方法: 尋找X計數行。 逐一看是否有一致性28天SQL多選SELECT太慢(7分鐘)

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)) 

感謝您的幫助!

+0

用一個一個的匹配來替換CONCAT,否則它會比較字符串並且太慢。 – sashkello

+0

正如davek所說,我認爲將'WHERE IN'子句改爲'INNER JOIN'可以解決這個問題。 – rAy

+0

爲什麼你有一個雙'%'通配符?你的意思是使用'__'代替嗎? – 2013-07-20 10:12:43

回答

1

NOT LIKE加上通配符前綴的術語是索引使用的殺手。

您也可以嘗試用inner join替換IN +行內表:優化程序是否運行NOT LIKE查詢兩次(請參閱您的解釋計劃)?

它看起來像你可能會使用MySQL,在這種情況下,你可以建立一個基於

efi_id 
irsz 
ucase(city) 
ucase(address)) 

哈希列和列直接比較。這是在MySql中實現散列連接的一種方式。

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天查看,而是查看周內的所有記錄,然後是該週期前四周的所有記錄。儘管存在這種微妙的差異,但它仍然在一週時間週期之前的四周時間內識別出誘惑。