我有一个想要优化的查询,需要29秒才能完成。我已经尝试创建了一个联合连接的视图,但结果却更糟。
select o.orderno, o.orderdate, c.lastname
from orders o
join (select
`hdb`.`contacts`.`CONTACTID` AS `CONTACTID`,
`hdb`.`contacts`.`LASTNAME` AS `LASTNAME`
from `hdb`.`contacts`
union
select
`sugarcrm`.`contacts`.`id` AS `CONTACTID`,
`sugarcrm`.`contacts`.`last_name` AS `LASTNAME`
from `sugarcrm`.`contacts` ) c on c.CONTACTID = o.CONTACTID
order by orderno desc
limit 0,100000000
在mysql慢查询日志下,我得到以下部分:
select
`hdb`.`contacts`.`CONTACTID` AS `CONTACTID`,
`hdb`.`contacts`.`CLIENTID` AS `CLIENTID`,
concat(`hdb`.`contacts`.`FIRSTNAME`,_utf8' ',coalesce(`hdb`.`contacts`.`INITIALS`,_utf8'')) AS `FIRSTNAME`,
`hdb`.`contacts`.`LASTNAME` AS `LASTNAME`,
`hdb`.`contacts`.`PHONE` AS `PHONE`,
`hdb`.`contacts`.`FAX` AS `FAX`,
`hdb`.`contacts`.`DEPARTMENT` AS `DEPARTMENT`,
`hdb`.`contacts`.`TITLE` AS `TITLE`,
`hdb`.`contacts`.`INFO` AS `INFO`,
`hdb`.`contacts`.`SALUTATION` AS `SALUTATION`,
`hdb`.`contacts`.`EMAIL` AS `EMAIL`,
CASE
WHEN `hdb`.`contacts`.`ACTIVE` != 0 THEN 0
ELSE 1
END DELETED,
'paradox' AS `SOURCEDATABASE`
from `hdb`.`contacts`
union
select
`sugarcrm`.`contacts`.`id` AS `CONTACTID`,
`sugarcrm`.`accounts_contacts`.`account_id` AS `CLIENTID`,
`sugarcrm`.`contacts`.`first_name` AS `FIRSTNAME`,
`sugarcrm`.`contacts`.`last_name` AS `LASTNAME`,
`sugarcrm`.`contacts`.`phone_work` AS `PHONE`,
`sugarcrm`.`contacts`.`phone_fax` AS `FAX`,
`sugarcrm`.`contacts`.`department` AS `department`,
`sugarcrm`.`contacts`.`title` AS `title`,
`sugarcrm`.`contacts`.`description` AS `INFO`,
`sugarcrm`.`contacts`.`salutation` AS `salutation`,
`sugarcrm`.`email_addresses`.`email_address` AS `Email`,
`sugarcrm`.`contacts`.`deleted` AS DELETED,
'sugar' AS `SOURCEDATABASE`
from (((`sugarcrm`.`contacts`
left join `sugarcrm`.`email_addr_bean_rel`
on((`sugarcrm`.`contacts`.`id` = `sugarcrm`.`email_addr_bean_rel`.`bean_id`)))
left join `sugarcrm`.`accounts_contacts`
on((`sugarcrm`.`contacts`.`id` = `sugarcrm`.`accounts_contacts`.`contact_id`)))
join `sugarcrm`.`email_addresses`
on((`sugarcrm`.`email_addr_bean_rel`.`email_address_id` = `sugarcrm`.`email_addresses`.`id`)))
但如果单独运行,这会很快运行。使用说明给我以下内容。
1, PRIMARY, o, ALL, , , , , 6085, Using temporary; Using filesort
1, PRIMARY, <derived2>, ALL, , , , , 18877, Using where
2, DERIVED, contacts, ALL, , , , , 8009,
3, UNION, contacts, ALL, , , , , 10251,
, UNION RESULT, <union2,3>, ALL, , , , , ,
答案 0 :(得分:1)
对于您的热门查询,我会将其更改为双左连接到每个相应的联系人表...也就是说,看起来客户的联系人ID应该是其中的任何一个(除非您有其他联系表) 。也就是说,左连接比执行预查询/连接更快。对于名称,我会case / when ...如果一个表没有匹配(通过IS NULL),则使用另一个表中的名称,反之亦然...如果它有值,用它。然后,只需确保您的订单表上有订单号的索引。
select
o.orderno,
o.orderdate,
CASE when hc.contactid is null
then sc.last_name else hc.lastname end as LastName
from
orders o
LEFT JOIN hdb.contacts hc
ON o.ContactID = hc.ContactID
LEFT JOIN sugarcrm.contacts sc
ON o.ContactID = sc.id
order by
orderno desc
limit 0, 100000000
如果您有其他联系人表,但只关心那些与“hc”和“sc”别名表相关联的表,我会为
添加一个WHERE子句WHERE hc.contactID IS NOT NULL
OR sc.id IS NOT NULL
确保至少有一个表有匹配。