2016-05-13 92 views
1


我知道每個人都討厭指定問題,但我需要你的幫助。 所以 - 那是代碼。它必須獲取信息的用戶如何優化這個mysql查詢(max,replace,left join)?

select 
c.id, 
c.firstName, 
c.lastName, 
... 
dt.code as docCode, 
dt.name as docName, 
replace(replace(replace(replace(replace(cc.contact, ' ',''), '(',''), ')', ''), '-', ''), '+', '') as homePhone, 
replace(replace(replace(replace(replace(cc1.contact, ' ',''), '(',''), ')', ''), '-', ''), '+', '') as cellPhone 
     from Client c 
     left join ClientPolicy p on p.id=(select max(pp.id) 
              from ClientPolicy pp 
              where 
              pp.client_id = c.id 
              and pp.deleted = 0) 
     left join rbPolicyType pt on pt.id = p.policyType_id 
     left join ClientDocument d on d.id =(SELECT MAX(dd.id) 
              FROM ClientDocument dd 
              WHERE 
              dd.client_id = c.id 
              and dd.deleted = 0) 
     left join rbDocumentType dt on dt.id = d.documentType_id and dt.code IN ('1') 
     left join ClientContact cc ON cc.id = (select MAX(ccc.id) 
               FROM ClientContact ccc 
               where 
               ccc.client_id = c.id 
               and ccc.deleted = 0 
               and ccc.contactType_id = 1) 
     left join ClientContact cc1 ON cc1.id = (SELECT MAX(ccc1.id) 
               FROM ClientContact ccc1 
               WHERE 
               ccc1.client_id = c.id 
               and ccc1.deleted = 0 
               and ccc1.contactType_id = 3) 
    where 
c.deleted = 0 
and c.firstName like '%' 
and c.patrName like '%' 
and c.lastName like '%' 
and replace(replace(replace(replace(replace(cc.contact, ' ',''), '(',''), ')', ''), '-', ''), '+', '') like '%521%' 
and replace(replace(replace(replace(replace(cc1.contact, ' ',''), '(',''), ')', ''), '-', ''), '+', '') like '%8905%' 

每隔%意味着用戶可以插入一些數據存在,例如like '%8905%

關於INDEX
我添加索引類似下面,所以這樣一來,我肯定不會幫助

INDEX client_insurer (client_id, insurer_id),  
    INDEX policyType_id (policyType_id), 
    INDEX Serial_Num (serial, number), 

關於replace(replace...
我相信,正則表達式會給我只需1秒以下,ADDI NG這個
How do you extract a numerical value from a string in a MySQL query?
溶合不reduse時間(實際添加5秒以上)

我不知道(MB粘貼條件從wherejoin?)如何使其更快。請幫幫我。

回答

0

那麼,你沒有添加explain,沒有關於你的數據的信息,沒有表結構,沒有關於(有用的)索引的信息。沒有這個,優化只是一個受過教育的猜測。

但是我會盡力去嘗試。

我想嘗試一系列的子查詢,因爲無論如何因爲喜歡你必須經歷所有的數據。

select 
c.id, 
c.firstName, 
c.lastName, 
... 
dt.code as docCode, 
dt.name as docName, 
cphone1 as as homePhone, 
cphone3 as cellPhone 
from 

(select *, 
    replace(replace(replace(replace(replace(cc.contact, ' ',''), '(',''), ')', ''), '-', ''), '+', '') as cphone1, 
    replace(replace(replace(replace(replace(cc1.contact, ' ',''), '(',''), ')', ''), '-', ''), '+', '') as cphone3 
    from 
    (select c.id, 
    (select max(pp.id) from ClientPolicy pp 
    where pp.client_id = c.id and pp.deleted = 0) as pmax, 
    (select max(dd.id) FROM ClientDocument dd 
    WHERE dd.client_id = c.id and dd.deleted = 0) as dmax, 
    (select MAX(ccc.id) FROM ClientContact ccc 
    where ccc.client_id = c.id and ccc.deleted = 0 
    and ccc.contactType_id = 1) as cmax1, 
    (SELECT MAX(ccc1.id) FROM ClientContact ccc1 
    WHERE ccc1.client_id = c.id and ccc1.deleted = 0 
    and ccc1.contactType_id = 3) as cmax3 
    from Client c   
    where c.deleted = 0 
    and c.firstName like '%' 
    and c.patrName like '%' 
    and c.lastName like '%' 
) as clientbase 
    join ClientContact cc on cc.id = clientbase.cmax1 
    join ClientContact cc1 on cc1.id = clientbase.cmax3 
) as clientnamed 
join client c on c.id = clientnamed.id 
left join ClientPolicy p on p.id=clientnamed.pmax 
left join rbPolicyType pt on pt.id = p.policyType_id 
left join ClientDocument d on d.id = clientnamed.dmax 
left join rbDocumentType dt on dt.id = d.documentType_id and dt.code = 1 
where cphone1 like '%521%' and cphone3 like '%8905%'; 

如果你的搜索參數「%521%」或「%8905%」是可選的(例如,不總是給出),你必須使用left join ClientContact cc(同爲CC1),但隨後沒有cphone1 like '%521%'where(與cphone3 like '%8905%'相同),因爲它將再次充當join。 (並且您的like '%'實際上應該也不在此處。)

如果您能夠在新列中以乾淨方式使用電話號碼(例如,通過觸發器進行更新),您可能會獲得改進。

我們索引:

你絕對必須有id作爲主鍵。

爲客戶端(id,已刪除),ClientPolicy(id,已刪除)和ClientDocument(已刪除)創建索引。

您應該嘗試ClientContact上的索引(id,deleted,contact_type)或(id,contact_type,deleted) - 取決於您的數據:如果您有很多刪除條目,則第一個應該更好,否則秒一。

如果這些索引會產生可測量的效果取決於您的數據,但由於您沒有告訴我們有關您的數據的任何信息,請嘗試它(有很多索引會減慢插入/更新速度,所以不要垃圾郵件索引;但是,您再也沒有告訴我們關於數據的任何信息,因此您必須自己嘗試一下。)

對於任何跟進,你必須至少添加以下

  • explain,看看有什麼MySQL是實際上做
  • explain子查詢select c.id, (select max(pp.id) from ClientPolicy pp ... c.lastName like '%'周圍無碼
  • 花費的時間得到整個代碼的結果,並只是上述子查詢
+0

嗯,謝謝你,我昨天讀你的評論,沒有時間回答。我會添加你所有的信息,你需要。另外,我的teamleader強烈贊同你的索引,例如(id,deleted)。 PS非常感謝你 –