2013-06-12 100 views
0

我有一个要优化的查询。这两个工会执行separatley运行良好,但只要我包括内部连接,它需要长达57秒。我该如何解决这个问题。我的查询如下使用联合左连接和内连接优化查询

SELECT 
    p.PROJID, 
    p.StartDate, 
    o.ORDERNO, 
    p.PROJCODE, 
    p.PROJECT, 
    cat.type AS CATEGORY, 
    p.AREA, 
    p.STATE, 
    p.COUNTRY, 
    p.VALUE, 
    p.PROCESSOR, 
    p.PROJINFO, 
    p.NES, 
    p.SPECSALE, 
    p.OFFICE, 
    p.DEPTCODE, 
    p.INTERNLCHG, 
    p.INTERCOCHG, 
    p.LORM, 
    p.PERCENT, 
    d.COMPANY, 
    CONCAT(
     d.LASTNAME, 
     ", ", 
     d.FIRSTNAME 
    ) AS Contact 
FROM 
    (
     (
      SELECT 
       * 
      FROM 
       (
        SELECT 
         `clients`.`CLIENTID` AS `CLIENTIDA`, 
         `clients`.`COMPANY` AS `COMPANY` 
        FROM 
         `hdb`.`clients` 
        UNION 
         SELECT 
          `accounts`.`id` AS `CLIENTIDA`, 
          `accounts`.`name` AS `COMPANY` 
         FROM 
          `sugarcrm`.`accounts` 
       ) AS a 
      INNER JOIN (
       SELECT 
        `hdb`.`contacts`.`CONTACTID` AS `CONTACTID`, 
        `hdb`.`contacts`.`CLIENTID` AS `CLIENTIDC`, 
        `hdb`.`contacts`.`FIRSTNAME` AS `FIRSTNAME`, 
        `hdb`.`contacts`.`LASTNAME` AS `LASTNAME` 
       FROM 
        `hdb`.`contacts` 
       UNION 
        SELECT 
         `sugarcrm`.`contacts`.`id` AS `CONTACTID`, 
         `sugarcrm`.`accounts_contacts`.`account_id` AS `CLIENTIDC`, 
         `sugarcrm`.`contacts`.`first_name` AS `FIRSTNAME`, 
         `sugarcrm`.`contacts`.`last_name` AS `LASTNAME` 
        FROM 
         `sugarcrm`.`contacts` 
        LEFT JOIN `sugarcrm`.`accounts_contacts` ON `sugarcrm`.`contacts`.`id` = `sugarcrm`.`accounts_contacts`.`contact_id` 
      ) AS c ON a.CLIENTIDA = c.CLIENTIDC 
     ) AS d 
    ) 
INNER JOIN (
    (
     projects AS p 
     INNER JOIN orders AS o ON p.ORDERNO = o.ORDERNO 
    ) 
    INNER JOIN category AS cat ON p.category_id = cat.category_id 
) ON d.CONTACTID = o.CONTACTID 

解释这一规定如下:

1, PRIMARY, cat, ALL, PRIMARY, , , , 10, 
1, PRIMARY, p, ref, FK_orders_projects,FK_category_projects_idx, FK_category_projects_idx, 5, hdb.cat.category_id, 400, Using where 
1, PRIMARY, o, eq_ref, PRIMARY, PRIMARY, 4, hdb.p.ORDERNO, 1, 
1, PRIMARY, <derived2>, ALL, , , , , 18878, Using where 
2, DERIVED, <derived3>, ALL, , , , , 7087, 
2, DERIVED, <derived5>, ALL, , , , , 18879, Using where 
5, DERIVED, contacts, ALL, , , , , 8261, 
6, UNION, contacts, ALL, , , , , 10251, 
6, UNION, accounts_contacts, ref, idx_contid_del_accid, idx_contid_del_accid, 111, sugarcrm.contacts.id, 1, Using index 
, UNION RESULT, <union5,6>, ALL, , , , , , 
3, DERIVED, clients, ALL, , , , , 2296, 
4, UNION, accounts, ALL, , , , , 4548, 
, UNION RESULT, <union3,4>, ALL, , , , , , 

没有工会原来的查询需要0.125秒

SELECT p.PROJID, p.StartDate, o.ORDERNO, p.PROJCODE, p.PROJECT, cat.type AS CATEGORY, p.AREA, p.STATE, p.COUNTRY, 
p.VALUE, p.PROCESSOR, p.PROJINFO, p.NES, p.SPECSALE, p.OFFICE, p.DEPTCODE, p.INTERNLCHG, p.INTERCOCHG, p.LORM, 
p.PERCENT, a.COMPANY, CONCAT(c.LASTNAME, ", ", c.FIRSTNAME) AS Contact 
FROM (clients AS a 
INNER JOIN contacts AS c ON a.CLIENTID =c.CLIENTID) 
INNER JOIN ((projects AS p INNER JOIN orders AS o ON p.ORDERNO = o.ORDERNO) 
INNER JOIN category AS cat ON p.category_id = cat.category_id) ON c.CONTACTID = o.CONTACTID 
ORDER BY p.PROJID, a.COMPANY; 

这一解释提供了以下内容:

1, SIMPLE, cat, ALL, PRIMARY, , , , 10, Using temporary; Using filesort 
1, SIMPLE, p, ref, FK_orders_projects,FK_category_projects_idx, FK_category_projects_idx, 5, hdb.cat.category_id, 400, Using where 
1, SIMPLE, o, eq_ref, PRIMARY,FK_contacts_orders, PRIMARY, 4, hdb.p.ORDERNO, 1, 
1, SIMPLE, c, eq_ref, PRIMARY,FK_clients_contacts, PRIMARY, 52, hdb.o.CONTACTID, 1, 
1, SIMPLE, a, eq_ref, PRIMARY, PRIMARY, 52, hdb.c.CLIENTID, 1, 

查询点:

SELECT 
    p.PROJID, 
    p.StartDate, 
    o.ORDERNO, 
    p.PROJCODE, 
    p.PROJECT, 
    cat.type AS CATEGORY, 
    p.AREA, 
    p.STATE, 
    p.COUNTRY, 
    p.VALUE, 
    p.PROCESSOR, 
    p.PROJINFO, 
    p.NES, 
    p.SPECSALE, 
    p.OFFICE, 
    p.DEPTCODE, 
    p.INTERNLCHG, 
    p.INTERCOCHG, 
    p.LORM, 
    p.PERCENT, 
    a.COMPANY, 
    CONCAT(
     c.LASTNAME, 
     ", ", 
     c.FIRSTNAME 
    ) AS Contact 
FROM 
    (
     view_accounts_sugar_hdb AS a 
     INNER JOIN view_contacts_sugar_hdb AS c ON a.CLIENTID = c.CLIENTID 
    ) 
INNER JOIN (
    (
     projects AS p 
     INNER JOIN orders AS o ON p.ORDERNO = o.ORDERNO 
    ) 
    INNER JOIN category AS cat ON p.category_id = cat.category_id 
) ON c.CONTACTID = o.CONTACTID 
ORDER BY 
    p.PROJID, 
    a.COMPANY; 

这需要340秒。

回答

1

这一个肯定比我帮助你的最后一个更丑陋:)...总之,同样的原则适用。为了将来,请尽量了解我在这里做什么。先写入JOIN关系以知道数据来自何处。另外,看看我的缩进......我在每个级别上都展示了可读性。

Orders -> Projects -> Categories... 

然后,通过

Orders -> Contacts -> Clients 

终于到了SugarCRM的接触对于那些在正常的客户表中的路径...

Orders -> Accounts_Contacts -> Accounts 

所以,现在你有关系的设置(和别名),这跟类似的最后回答实施LEFT-JOIN到正常联系人/客户端与CRM联系人/帐户。

这些字段列表在订单,产品和类别表格中很简单,因为这些表格非常直接。这使得刚刚“谁/客户”的信息,其中左JOIN的用武之地。如果正常的客户端为空,则使用CRM版本领域,否则使用普通客户端领域...

SELECT 
     P.PROJID, 
     P.StartDate, 
     O.ORDERNO, 
     P.PROJCODE, 
     P.PROJECT, 
     cat.`type` AS CATEGORY, 
     P.AREA, 
     P.STATE, 
     P.COUNTRY, 
     P.VALUE, 
     P.PROCESSOR, 
     P.PROJINFO, 
     P.NES, 
     P.SPECSALE, 
     P.OFFICE, 
     P.DEPTCODE, 
     P.INTERNLCHG, 
     P.INTERCOCHG, 
     P.LORM, 
     P.PERCENT, 
     CASE when HCLIENT.ClientID IS NULL 
      then SCLIENT.`name` 
      ELSE HCLIENT.Company end as Company, 
     CASE when HCLIENT.ClientID IS NULL 
      then CONCAT(SCT.LAST_NAME, ", ", SCT.FIRST_NAME) 
      ELSE CONCAT(HCT.LASTNAME, ", ", HCT.FIRSTNAME) end as Contact 
    FROM 
     orders O 
     JOIN projects P 
      ON O.OrderNo = P.OrderNo 
      JOIN category AS cat 
       ON p.category_id = cat.category_id 

     LEFT JOIN hdb.contacts HCT 
      ON O.ContactID = HCT.ContactID 
      LEFT JOIN hdb.clients HCLIENT 
       ON HCT.ClientID = HCLIENT.ClientID 

     LEFT JOIN sugarcrm.contacts SCT 
      ON O.ContactID = SCT.ID 
      LEFT JOIN sugarcrm.accounts_contacts SAC 
       ON SCT.ID = SAC.contact_id 
       LEFT JOIN sugarcrm.accounts SCLIENT 
        ON SCT.account_id = SCLIENT.ID 

我会也对性能改进感兴趣。

+0

我收到一个错误代码:1054。'on子句'中的未知列'p.category_id' – shorif2000

+0

性能为0.686秒。 – shorif2000

+0

在我原来的查询中,我有我的联合,我创建了一个视图,他们是否有可能在这些查询中使用视图?我将包括在我的问题 – shorif2000