在其他连接的 select 语句中优化联合连接 [英] optimizing a union join inside select statement of other joins

查看:54
本文介绍了在其他连接的 select 语句中优化联合连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个由 3 -4 部分构建的查询.一旦我添加了带有 join 的 union 连接,这需要超过 140 秒才能运行.如何更改联合连接以更快地执行它.

I have a query I built in 3 -4 parts. This takes over 140secs to run once I add the union join with join. How can I change the union join to execute it faster.

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 的表别名需要很长时间才能执行.然后我需要把它变成一个视图

The table alias called testing is the one taking long to execute. I need to then turn this into a view

原始查询没有加入 Sugarcrm.

Original query without the joining of 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`

推荐答案

您的 LEFT JOIN 从 Sugarcrm.contacts 到 Sugarcrm.email_addr_bean_rel在 id=bean_id 上没问题,但是您对 Primary_Address = 1 的测试OR(主地址不是 NULL AND primary_address <> 0 )是浪费.

Your LEFT JOIN from sugarcrm.contacts to sugarcrm.email_addr_bean_rel ON the id=bean_id is ok, but then your test for Primary_Address = 1 OR ( primary address IS NOT NULL AND primary_address <> 0 ) is wasteful.

非空意味着它有一个值.1 的第一个限定符没问题,但随后您测试任何不等于 0 的地址(因此 1 是,但 2、3、400、1809 或任何其他号码.那么为什么不直接采用我的简化方式呢.

Not null mean it has a value. The first qualifier of 1 is ok, but then you test for any address not equal to 0 (thus 1 is, but so is 2, 3, 400, 1809 or any other number. So why not just take how I've simplified it.

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

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

I don't mind helping, but from now on, you should take a look at what I'm doing... Establish the relationships... Start with the basis of your data (orders) and look at ONE PATH on how to connect to your "contacts" table... Write those joins (as left-joins). THEN, write your paths to the SUGAR account contacts and write THOSE joins (also left-joins). Don't try to prequery all possible contacts, but using the CASE/WHEN to determine which to get based on a null route vs not just as I have with the contact, client, company, etc. You will get the data from one path vs the other... just keep it consistent.

这篇关于在其他连接的 select 语句中优化联合连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆