优化其他连接的select语句中的联合连接

时间:2013-06-17 16:57:55

标签: mysql view query-optimization union

我有一个我用3 -4部分构建的查询。一旦我使用join添加union join,这将需要超过140secs才能运行。如何更改联合联接以更快地执行它。

SELECT
    testing.CLIENTID,
    testing.COMPANY,
    testing.CONTACT,
    testing.CONTACTID,
    `orders`.`ORDERNO` AS `ORDERNO`,
    `orders`.`BIDNO` AS `BIDNO`,
    `projects`.`PROJID` AS `PROJID`,
    `projects`.`PROJCODE` AS `PROJCODE`,
    `projects`.`StartDate` AS `StartDate`,
    `category`.`type` AS `CATEGORY`,
    `projects`.`country` AS `COUNTRY`,
    `projects`.`VALUE` AS `VALUE`,
    `projects`.`PROCESSOR` AS `PROCESSOR`,
    `projects`.`NES` AS `NES`,
    `projects`.`SPECSALE` AS `SPECSALE`,
    `projects`.`OFFICE` AS `OFFICE`,
    `projects`.`LORM` AS `LORM`,
    `lookupcountry`.`REGION` AS `REGION`
FROM
    (
        (
            (
                (
                    (
                        (
                            SELECT
                                contactmerge.CLIENTID,
                                contactmerge.CONTACT,
                                contactmerge.CONTACTID,
                                accountmerge.COMPANY
                            FROM
                                (
                                    SELECT
                                        `hdb`.`contacts`.`CONTACTID` AS `CONTACTID`,
                                        `hdb`.`contacts`.`CLIENTID` AS `CLIENTID`,
                                        concat(
                                            `hdb`.`contacts`.`FIRSTNAME`,
                                            " ",
                                            `hdb`.`contacts`.`LASTNAME`
                                        ) AS CONTACT,
                                        _utf8 'paradox' AS `SOURCEDATABASE`
                                    FROM
                                        `hdb`.`contacts`
                                    UNION
                                        SELECT
                                            `sugarcrm`.`contacts`.`id` AS `CONTACTID`,
                                            `sugarcrm`.`accounts_contacts`.`account_id` AS `CLIENTID`,
                                            concat(
                                                `sugarcrm`.`contacts`.`first_name`,
                                                " ",
                                                `sugarcrm`.`contacts`.`last_name`
                                            ) AS CONTACT,
                                            _utf8 'sugar' AS `SOURCEDATABASE`
                                        FROM
                                            (
                                                (
                                                    (
                                                        (
                                                            `sugarcrm`.`contacts`
                                                            LEFT JOIN `sugarcrm`.`email_addr_bean_rel` ON (
                                                                (
                                                                    (
                                                                        `sugarcrm`.`contacts`.`id` = `sugarcrm`.`email_addr_bean_rel`.`bean_id`
                                                                    )
                                                                    AND (
                                                                        (
                                                                            `sugarcrm`.`email_addr_bean_rel`.`primary_address` = 1
                                                                        )
                                                                        OR (
                                                                            (
                                                                                `sugarcrm`.`email_addr_bean_rel`.`primary_address` IS NOT NULL
                                                                            )
                                                                            AND (
                                                                                `sugarcrm`.`email_addr_bean_rel`.`primary_address` <> 0
                                                                            )
                                                                        )
                                                                    )
                                                                )
                                                            )
                                                        )
                                                        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`
                                                        )
                                                    )
                                                )
                                                LEFT JOIN `sugarcrm`.`accounts` ON (
                                                    (
                                                        `sugarcrm`.`accounts`.`id` = `sugarcrm`.`accounts_contacts`.`account_id`
                                                    )
                                                )
                                            )
                                ) AS contactmerge
                            LEFT JOIN (
                                SELECT
                                    CLIENTID,
                                    `hdb`.`clients`.`COMPANY` AS `COMPANY`
                                FROM
                                    `hdb`.`clients`
                                UNION
                                    SELECT
                                        id AS CLIENTID,
                                        `sugarcrm`.`accounts`.`name` AS `COMPANY`
                                    FROM
                                        `sugarcrm`.`accounts`
                            ) AS accountmerge ON contactmerge.CLIENTID = accountmerge.CLIENTID
                        ) AS testing
                    )
                    JOIN `orders` ON (
                        (
                            `testing`.`CONTACTID` = `orders`.`CONTACTID`
                        )
                    )
                )
                JOIN `projects` ON (
                    (
                        `orders`.`ORDERNO` = `projects`.`ORDERNO`
                    )
                )
            )
            JOIN `category` ON (
                (
                    `category`.`category_id` = `projects`.`category_id`
                )
            )
        )
        LEFT JOIN `lookupcountry` ON (
            (
                CONVERT (
                    `lookupcountry`.`COUNTRY` USING utf8
                ) = CONVERT (
                    `projects`.`country` USING utf8
                )
            )
        )
    )
ORDER BY
    `testing`.`COMPANY`,
    `projects`.`StartDate`

名为testing的表别名是执行时间很长的表。我需要将其转换为视图

原始查询,没有加入sugarcrm。

SELECT
    `clients`.`CORPORATE` AS `CORPORATE`,
    `clients`.`COMPANY` AS `COMPANY`,
    `clients`.`CLIENTID` AS `CLIENTID`,
    `contacts`.`CONTACTID` AS `CONTACTID`,
    concat(
            `contacts`.`LASTNAME`,
            `contacts`.`FIRSTNAME`,     
            `contacts`.`INITIALS`
    ) AS `Contact`,
    `orders`.`ORDERNO` AS `ORDERNO`,
    `orders`.`BIDNO` AS `BIDNO`,
    `projects`.`PROJID` AS `PROJID`,
    `projects`.`PROJCODE` AS `PROJCODE`,
    `projects`.`StartDate` AS `StartDate`,
    `category`.`type` AS `CATEGORY`,
    `projects`.`country` AS `COUNTRY`,
    `projects`.`VALUE` AS `VALUE`,
    `projects`.`PROCESSOR` AS `PROCESSOR`,
    `projects`.`NES` AS `NES`,
    `projects`.`SPECSALE` AS `SPECSALE`,
    `projects`.`OFFICE` AS `OFFICE`,
    `projects`.`LORM` AS `LORM`,
    `lookupcountry`.`REGION` AS `REGION`
FROM
    (
        (
            (
                (
                    (
                        `clients`
                        JOIN `contacts` ON (
                            (
                                `clients`.`CLIENTID` = `contacts`.`CLIENTID`
                            )
                        )
                    )
                    JOIN `orders` ON (
                        (
                            `contacts`.`CONTACTID` = `orders`.`CONTACTID`
                        )
                    )
                )
                JOIN `projects` ON (
                    (
                        `orders`.`ORDERNO` = `projects`.`ORDERNO`
                    )
                )
            )
            JOIN `category` ON (
                (
                    `category`.`category_id` = `projects`.`category_id`
                )
            )
        )
        LEFT JOIN `lookupcountry` ON (
            (
                CONVERT (
                    `lookupcountry`.`COUNTRY` USING utf8
                ) = CONVERT (
                    `projects`.`country` USING utf8
                )
            )
        )
    )
ORDER BY
    `clients`.`CORPORATE`,
    `clients`.`COMPANY`,
    `contacts`.`LASTNAME`,
    `projects`.`StartDate`

1 个答案:

答案 0 :(得分:2)

您从sugarcrm.contacts左下角加入Sugarcrm.email_addr_bean_rel 在id = bean_id上没问题,但是你对Primary_Address的测试= 1 OR(主地址IS NOT NULL和primary_address&lt;&gt; 0)是浪费。

非空意味着它有一个值。 1的第一个限定符是好的,但随后 你测试任何不等于0的地址(因此1是,但是2,3,400,1809或者是2) 任何其他数字。那么为什么不采取我如何简化它。

SELECT
      O.ORDERNO,
      O.BIDNO,

      CASE when c.ContactID IS NULL
         then sc.id
         ELSE c.contactid  END as ContactID,

      CASE when c.ContactID IS NULL
         then sac.account_id
         ELSE c.clientid   END as ClientID,

      CASE when c.ContactID IS NULL
         then concat( sc.first_name, " ", sc.last_name ) 
         ELSE concat( c.FIRSTNAME, " ", c.LASTNAME )  END as Contact,

      CASE when c.ContactID IS NULL
         then sCli.`name`
         ELSE cCli.Company  END as Company,

      CASE when c.ContactID IS NULL
         then _utf8 'sugar' 
         ELSE _utf8 'paradox'  END as SOURCEDATABASE,

      P.PROJID,
      P.PROJCODE,
      P.StartDate,
      Cat.`type` AS CATEGORY,
      P.`country` AS COUNTRY,
      P.`VALUE` AS `VALUE`,
      P.PROCESSOR,
      P.NES,
      P.SPECSALE,
      P.OFFICE,
      P.LORM,
      LC.REGION
   FROM 
      orders O
         JOIN projects P
            ON O.ORDERNO = P.ORDERNO
            JOIN category Cat 
               ON P.category_id = Cat.category_id
            LEFT JOIN lookupcountry LC
               ON CONVERT( P.`country` USING utf8 ) = CONVERT( LC.COUNTRY USING utf8 )

         LEFT JOIN hdb.contacts c
            ON  O.ContactID = c.ClientID
            LEFT JOIN hdb.clients cCli
               ON c.ClientID = cCli.ClientID

         LEFT JOIN sugarcrm.contacts sc
            ON O.ContactID = sc.id
            LEFT JOIN sugarcrm.accounts sCli
               ON sc.id = sCli.id
            LEFT JOIN sugarcrm.accounts_contacts sac
               ON sc.id = sac.contact_id
               LEFT JOIN sugarcrm.accounts Acc 
                  ON sac.account_id = Acc.id

            LEFT JOIN sugarcrm.email_addr_bean_rel EABR
               ON sc.id = EABR.bean_id
              AND EABR.primary_address IS NOT NULL
              LEFT JOIN sugarcrm.email_addresses EA 
                 ON EABR.email_address_id = EA.id
ORDER BY
   CASE when c.ContactID IS NULL
      then sCli.`name`
      ELSE cCli.Company  END,
   P.StartDate

我不介意帮忙,但从现在开始,你应该看看我在做什么......建立关系......从你的数据(订单)的基础开始,看看一条路径关于如何连接到“联系人”表...写这些连接(作为左连接)。然后,写下您到SUGAR帐户联系人的路径并写下THOSE联接(也是左联接)。不要尝试预先查询所有可能的联系人,而是使用CASE / WHEN来确定基于空路由获得哪些联系,而不仅仅是我与联系人,客户,公司等的联系。您将从一条路径获取数据与其他人相比......只是保持一致。