如何优化返回数百万条记录的SQL查询

时间:2014-04-10 04:56:33

标签: sql sql-server sql-server-2005

以下使用的所有示例目前仅适用于一个销售组织,我们将来可能会有更多不同的salesOrganization编号。

我有6张表,有数百万条记录。此表由执行SSIS包填充。

select count(*) from tmp_materials --11,02,032

select count(*) from tbl_VendorLogoData --20,41,501
select count(*) from TBL_Image_EDV --4,44,063
select count(*) from TBL_EXTPRODUCTATTRIBUTES_EDV  -- 2,06,15,572
select count(*) from TBL_Accessories_EDV --10,11,568
select count(*) from TBL_SimilarSku --64,10,408

我有一个存储过程,用于从这些表中选择不同的记录

SELECT  DISTINCT    'MD' AS [COMPANYCD]
                    , MAIN.MATERIAL AS [MATERIAL]
                    , ISNULL(UPPER(IMG.[lowprovider]),'')  AS [LOW_IMAGE]
                    , ISNULL(UPPER(IMG.[midprovider]), '') AS [MID_IMAGE]
                    , ISNULL(UPPER(IMG.[highprovider]), '') AS [HIGH_IMAGE]
                    , ISNULL(UPPER(VS.isLogo),'') AS [VENDOR_LOGO]
                    , ISNULL(UPPER(DS.PROVIDER), '') AS [DATASHEET]
                    , ISNULL(ACC.AccessoryMaterial, '') AS [OPT_ACC]
                    , ISNULL(UPPER(ACC.Provider), '') AS [OPT_ACC_PROVIDER]     
                    , ISNULL(SS.Similarsku, '') AS [SIMILAR_SKU]
                    , ISNULL(UPPER(SS.ProviderName), '') AS [SIMILAR_SKU_PROVIDER]
FROM            tmp_materials MAIN WITH (NOLOCK)
LEFT OUTER JOIN TBL_Image_EDV IMG WITH (NOLOCK) ON MAIN.MATERIAL = IMG.MATERIAL AND MAIN.salesOrg = IMG.SalesOrganization
LEFT OUTER JOIN TBL_EXTPRODUCTATTRIBUTES_EDV DS WITH (NOLOCK) ON MAIN.MATERIAL = DS.SKUNBR AND MAIN.salesOrg = DS.SalesOrganization
LEFT OUTER JOIN TBL_Accessories_EDV ACC WITH (NOLOCK) ON MAIN.MATERIAL = ACC.ParentSKU AND MAIN.salesOrg = DS.SalesOrganization
LEFT OUTER JOIN TBL_SimilarSku SS WITH (NOLOCK) ON MAIN.MATERIAL = SS.ParentSKU AND MAIN.salesOrg = DS.SalesOrganization
LEFT OUTER JOIN tbl_VendorLogoData VS WITH (NOLOCK) ON MAIN.MATERIAL = VS.SKU AND MAIN.salesOrg = VS.Salesorganization
WHERE           MAIN.salesOrg = @SALESORGANIZATION
                AND (CASE   WHEN IMG.MATERIAL IS NULL AND DS.SKUNBR IS NULL  AND ACC.ParentSKU IS NULL  AND SS.ParentSKU IS NULL AND VS.SKU IS NULL
                            THEN 0 ELSE 1 END) = 1
                AND DS.Provider <> 'novalue' 
                AND SS.RecordIdentifier like '%@@%'
                AND ACC.RecordIdentifier like '%@@%'
                AND ACC.accessorySku LIKE '%@@%' 

这些过程的参数是@SALESORGANIZATION这用于填充报告。我正在为多个销售组织值运行它。但对于其中一个销售组织来说,生成数据需要5个多小时。

似乎我需要编写一个循环,但发现难以继续多个连接任何建议?

请建议我如何优化此查询?谢谢你的帮助。

您有执行计划文件SQL Execution Plan

1 个答案:

答案 0 :(得分:0)

尝试包含更多条件以提高效果。

在所有LEFT OUTER JOIN检查中直接包含您的参数并尝试避免使用JOINDE表 e.g

LEFT OUTER JOIN TBL_Image_EDV IMG WITH (NOLOCK) ON 
MAIN.MATERIAL = IMG.MATERIAL 
AND MAIN.salesOrg = IMG.SalesOrganization 
AND IMG.SalesOrganization=@SALESORGANIZATION

在WHERE中添加条件

AND SS.RecordIdentifier like '%@@%'

应该是

(SS.id IS NOT NULL AND SS.RecordIdentifier like '%@@%')

因此,您首先切割没有关系的行

更新

还有一个想法

尝试

INNER JOIN (select * 
                 from TBL_Accessories_EDV 
                 where RecordIdentifier like '%@@%'
                   AND accessorySku LIKE '%@@%') ACC WITH (NOLOCK) 
 ON MAIN.MATERIAL = ACC.ParentSKU AND MAIN.salesOrg = DS.SalesOrganization

仅限制您稍后过滤掉的记录