0

我有一个要优化的查询。两个执行分离的联合运行良好,但是一旦我包含内部连接,它最多需要 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 秒。

4

1 回答 1

1

这个绝对比我帮助你的上一个更丑:)...无论如何,同样的原则适用。对于未来,请尝试了解我在这里做什么。首先编写 JOIN 关系以了解您的数据来自何处。另外,看看我的缩进......我在每个级别都显示了可读性。

Orders -> Projects -> Categories...

然后,普通客户表中的路径通过

Orders -> Contacts -> Clients

终于到了 SugarCRM 联系人...

Orders -> Accounts_Contacts -> Accounts

因此,既然您已经设置了关系(和别名),这与将 LEFT-JOIN 实施到普通联系人/客户与 CRM 联系人/帐户的最后一个答案类似。

Order、Products 和 Category 表上的字段列表很简单,因为它们非常直接。这仅留下 LEFT-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

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

于 2013-06-12T11:41:40.927 回答