优化此SQL查询?

时间:2018-03-21 10:52:15

标签: mysql sql database rdbms

我正在使用MySQL DB。我有两张桌子 -

  1. Product_Data(它包含一些列,包括PK productDataId)
  2. Product_Data_Link(它有5列Id(PK),productDataId(FK),LinkTypeId,IsActive,ProductDataLinkUrl)
  3. 我在一个多个产品的服务调用中运行此查询。有没有办法优化它以便快速执行。

    select
        link1.ProductDataLinkUrl as ProductDataUrl1,
        link2.ProductDataLinkUrl as ProductDataUrl2,
        link3.ProductDataLinkUrl as ProductDataUrl3 ,
        link4.ProductDataLinkUrl as ProductDataUrl4 
    FROM
        product_data pd 
    left join
        product_data_links link1 
            on link1.ProductDataId = pd.ProductDataId 
            and link1.ProductDataLinkTypeId = 1 
            and link1.ProductDataLinkIsActive = 1 
    left join
        product_data_links link2 
            on link2.ProductDataId = pd.ProductDataId 
            and link2.ProductDataLinkTypeId = 2 
            and link2.ProductDataLinkIsActive = 1 
    left join
        product_data_links link3 
            on link3.ProductDataId = pd.ProductDataId 
            and link3.ProductDataLinkTypeId = 3 
            and link3.ProductDataLinkIsActive = 1 
    left join
        product_data_links link4 
            on link4.ProductDataId = pd.ProductDataId 
            and link4.ProductDataLinkTypeId = 4 
            and link4.ProductDataLinkIsActive = 1 
    WHERE
        pd.ProductDataId = 99999
    

2 个答案:

答案 0 :(得分:5)

您的查询应该可以使用以下索引:

  • product_data(ProductDataId)
  • product_data_links(ProductDataId, ProductDataLinkTypeId, ProductDataLinkIsActive)

在某些情况下,使用group by

会更快
  select max(case when ProductDataLinkTypeId = 1 then ProductDataLinkUrl end) as ProductDataUrl1,
         max(case when ProductDataLinkTypeId = 2 then ProductDataLinkUrl end) as ProductDataUrl2,
         max(case when ProductDataLinkTypeId = 3 then ProductDataLinkUrl end) as ProductDataUrl3,
         max(case when ProductDataLinkTypeId = 4 then ProductDataLinkUrl end) as ProductDataUrl4
  from product_data_links pdl
  where ProductDataId = 99999 and
        ProductDataLinkIsActive = 1 and
        ProductDataLinkTypeId in (1, 2, 3, 4);

您希望此查询的第二个索引。

答案 1 :(得分:0)

我认为在公共相关字段中添加索引很重要:newIndex(ProductDataId,ProductDataLinkTypeId,ProductDataLinkIsActive,ProductDataLinkUrl)

然后,我喜欢子查询,因为它只带来了必需的字段,而不是带有连接的整个表。

(select 
    (select l1.ProductDataLinkUrl from product_data_links l1 where l1.ProductDataId = pd.ProductDataId 
        and l1.ProductDataLinkTypeId = 1 
        and l1.ProductDataLinkIsActive = 1 ) as ProductDataUrl1, 

    (select l2.ProductDataLinkUrl from product_data_links l2 where l2.ProductDataId = pd.ProductDataId 
        and l2.ProductDataLinkTypeId = 2
        and l2.ProductDataLinkIsActive = 1 ) as ProductDataUrl2, 

    (select l3.ProductDataLinkUrl from product_data_links l3 where l3.ProductDataId = pd.ProductDataId 
        and l3.ProductDataLinkTypeId = 3 
        and l3.ProductDataLinkIsActive = 1 ) as ProductDataUrl3,

    (select l4.ProductDataLinkUrl from product_data_links l4 where l4.ProductDataId = pd.ProductDataId 
        and l4.ProductDataLinkTypeId = 4 
        and l4.ProductDataLinkIsActive = 1 ) as ProductDataUrl4
FROM
    product_data pd 
WHERE
    pd.ProductDataId = 99999)

我会在重构的每一步之后安排时间和结果组。

祝你好运!