我知道每个人都讨厌提出问题,但我需要你的帮助。
所以 - 这就是代码。它必须获取用户的信息
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
' s
我添加了下面的索引,所以这样,我肯定无法帮助
INDEX client_insurer (client_id, insurer_id),
INDEX policyType_id (policyType_id),
INDEX Serial_Num (serial, number),
关于replace(replace...
我相信正则表达式会给我少1秒的时间并添加这个
How do you extract a numerical value from a string in a MySQL query?
溶剂化不会减少时间(实际上增加5秒)
我不知道(从where
到join
的mb粘贴条件?)如何让它更快。求你帮帮我。
答案 0 :(得分: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相同),但是没有{{1在cphone1 like '%521%'
{同一where
)中,因为它会再次充当cphone3 like '%8905%'
。 (而你的join
实际上也不应该在那里。)
如果您能够在新列中以干净的方式使用电话号码(例如,通过触发器更新),您可能会得到改进。
现在索引:
您必须将like '%'
作为主键。
为Client(id,deleted),ClientPolicy(id,deleted)和ClientDocument(id,deleted)创建索引。
你应该在ClientContact上尝试索引(id,删除,contact_type)或(id,contact_type,删除) - 取决于你的数据:如果你有很多删除的条目,第一个应该更好,否则秒
如果这些索引具有可衡量的效果取决于您的数据,但由于您没有告诉我们有关您的数据的任何信息,请尝试它(拥有大量索引会降低您的插入/更新速度,所以不要垃圾邮件索引;但是,你没有告诉我们关于数据的任何信息,所以你必须自己试一试。)
对于任何后续操作,您必须至少添加以下内容
id
看看mysql究竟在做什么explain
表示没有周围代码的子查询explain