-1

我有一个要优化的查询,需要 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, , , , , , 
4

1 回答 1

1

对于您的顶级查询,我会将其更改为对每个相应的联系人表进行双左连接...也就是说,似乎客户的联系人 ID 应该在其中一个中(除非您有其他联系人表)。也就是说,左连接将比进行预查询/连接更快。对于名称,我会判断/何时...如果一个表没有匹配项(通过 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

确保至少有一个表有匹配项。

于 2013-06-11T13:04:35.427 回答