查询速度慢

时间:2018-06-22 14:09:25

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

所以我有这个查询

SELECT
    dbo.TQMNCR.NCRID,
    dbo.TQMPlantTable.PlantName AS 'Division',
    RTRIM(LTRIM(dbo.INVENTTABLE.ITEMGROUPID)) AS 'Item Process/Group',
    ISNULL(dbo.TQMNCRDEFECTTYPECODES.QTY,0) AS 'Defective Qty',
    CASE CATYPE
        WHEN 0 THEN 
            (CASE WHEN dbo.SALESLINE.SALESID = ''
                THEN ISNULL((PRICE * (PERCENTEXT / 100))  / NULLIF(dbo.INVENTTABLEMODULE.PRICEUNIT, 0), 0) * ISNULL(dbo.TQMNCRDEFECTTYPECODES.QTY,0)
                ELSE ISNULL((SALESPRICE * (PERCENTEXT / 100))  / NULLIF(dbo.SALESLINE.PRICEUNIT, 0), 0) * ISNULL(dbo.TQMNCRDEFECTTYPECODES.QTY,0) END)
        WHEN 2 THEN 
            (CASE WHEN dbo.TQMNCR.SALESID = ''
                THEN ISNULL((PRICE * (PERCENTINT / 100))  / NULLIF(dbo.INVENTTABLEMODULE.PRICEUNIT, 0), 0) * ISNULL(dbo.TQMNCRDEFECTTYPECODES.QTY,0)
                ELSE ISNULL((SALESPRICE * (PERCENTINT / 100))  / NULLIF(dbo.SALESLINE.PRICEUNIT, 0), 0) * ISNULL(dbo.TQMNCRDEFECTTYPECODES.QTY,0) END)
        ELSE 0 END AS 'Total Defective $',
    dbo.PRODTABLE.PRODPOOLID
    ,SCHED.qty,
    SUM(salesDollars.sales$) as 'sales Dollars',
    fc.YearMonth,
    HG.HighLevelItemGroupingCodeName
FROM
    dbo.TQMNCR 
    LEFT OUTER JOIN dbo.TQMDISPOSITION ON dbo.TQMNCR.DISPOSITIONID = dbo.TQMDISPOSITION.DISPOSITIONID 
    LEFT OUTER JOIN dbo.TQMCA_TABLE ON dbo.TQMCA_TABLE.NCRID = dbo.TQMNCR.NCRID 
    LEFT OUTER JOIN dbo.TQMNCRDEFECTTYPECODES ON dbo.TQMNCR.NCRID = dbo.TQMNCRDEFECTTYPECODES.NCRID
    LEFT OUTER JOIN dbo.TQMPlantTable ON TQMPlantTable.PlantID  = dbo.TQMNCR.PlantID
    LEFT OUTER JOIN dbo.INVENTTABLE ON dbo.TQMNCR.ITEMID = dbo.INVENTTABLE.ITEMID 
    LEFT OUTER JOIN dbo.INVENTTABLEMODULE ON dbo.INVENTTABLE.ITEMID = dbo.INVENTTABLEMODULE.ITEMID AND MODULETYPE = 2 
    LEFT OUTER JOIN dbo.SALESLINE ON dbo.SALESLINE.SALESID = dbo.TQMNCR.SALESID AND dbo.SALESLINE.ITEMID = dbo.TQMNCR.ITEMID 
    LEFT OUTER JOIN dbo.PRODTABLE ON dbo.TQMNCR.PRODID = dbo.PRODTABLE.PRODID
    inner join sched on sched.itemGroup = INVENTTABLE.itemgroupid
    inner join salesQty on salesQty.itemGroup = INVENTTABLE.itemgroupid
    inner join salesDollars on  salesDollars.itemgroup = INVENTTABLE.itemgroupid
    LEFT JOIN [MiscReportTables].[dbo].[FiscalCalendar] fc on SCHEDDATE between fc.StartDate and fc.EndDate
    left JOIN INVENTITEMGROUP IG on dbo.INVENTTABLE.ITEMGROUPID = IG.ITEMGROUPID
    LEFT JOIN Pmf_HighLevelItemGrouping HG on IG.HIGHLEVELITEM = HG.HighLevelItemGroupingCode
WHERE
    SCHEDDATE between @start1 and @end1
    AND
    dbo.TQMNCR.PlantID IN (SELECT [PLANTID]
                            FROM [Dynamics].[dbo].[TQMPLANTTABLE])
Group By TQMNCR.NCRID,TQMPlantTable.PLANTNAME,INVENTTABLE.ITEMGROUPID,TQMNCRDEFECTTYPECODES.QTY,TQMNCR.CATYPE,SALESLINE.SALESID,INVENTTABLEMODULE.PRICE,
TQMDISPOSITION.PERCENTEXT,INVENTTABLEMODULE.PRICEUNIT,INVENTTABLEMODULE.PRICEUNIT,SALESLINE.SALESPRICE,SALESLINE.PRICEUNIT,TQMNCR.SALESID,TQMDISPOSITION.PERCENTINT,PRODTABLE.PRODPOOLID,
sched.qty,salesQty.salesQTY,fc.YearMonth,HG.HighLevelItemGroupingCodeName`

运行缓慢,当我查看查询分析器时,我看到了

sort

因此,似乎排序(由于SUM和对应的group by所致)导致此查询运行缓慢。无论如何,我可以加快速度吗? group by很大,我是否需要在所有这些表上添加索引?

编辑:以下是该计划的链接:Explain Plan

1 个答案:

答案 0 :(得分:1)

您可以尝试通过子查询(或CTE)避免数十亿行的 HUGE GROUP BY

尝试类似的事情:

SELECT
    dbo.TQMNCR.NCRID,
    dbo.TQMPlantTable.PlantName AS 'Division',
    RTRIM(LTRIM(dbo.INVENTTABLE.ITEMGROUPID)) AS 'Item Process/Group',
    ISNULL(dbo.TQMNCRDEFECTTYPECODES.QTY,0) AS 'Defective Qty',
    CASE CATYPE
        WHEN 0 THEN 
            (CASE WHEN dbo.SALESLINE.SALESID = ''
                THEN ISNULL((PRICE * (PERCENTEXT / 100))  / NULLIF(dbo.INVENTTABLEMODULE.PRICEUNIT, 0), 0) * ISNULL(dbo.TQMNCRDEFECTTYPECODES.QTY,0)
                ELSE ISNULL((SALESPRICE * (PERCENTEXT / 100))  / NULLIF(dbo.SALESLINE.PRICEUNIT, 0), 0) * ISNULL(dbo.TQMNCRDEFECTTYPECODES.QTY,0) END)
        WHEN 2 THEN 
            (CASE WHEN dbo.TQMNCR.SALESID = ''
                THEN ISNULL((PRICE * (PERCENTINT / 100))  / NULLIF(dbo.INVENTTABLEMODULE.PRICEUNIT, 0), 0) * ISNULL(dbo.TQMNCRDEFECTTYPECODES.QTY,0)
                ELSE ISNULL((SALESPRICE * (PERCENTINT / 100))  / NULLIF(dbo.SALESLINE.PRICEUNIT, 0), 0) * ISNULL(dbo.TQMNCRDEFECTTYPECODES.QTY,0) END)
        ELSE 0 END AS 'Total Defective $',
    dbo.PRODTABLE.PRODPOOLID,
    SCHED.qty,
    salesDollars.[sales Dollars],
    fc.YearMonth,
    HG.HighLevelItemGroupingCodeName
FROM
    dbo.TQMNCR 
    LEFT OUTER JOIN dbo.TQMDISPOSITION ON dbo.TQMNCR.DISPOSITIONID = dbo.TQMDISPOSITION.DISPOSITIONID 
    LEFT OUTER JOIN dbo.TQMCA_TABLE ON dbo.TQMCA_TABLE.NCRID = dbo.TQMNCR.NCRID 
    LEFT OUTER JOIN dbo.TQMNCRDEFECTTYPECODES ON dbo.TQMNCR.NCRID = dbo.TQMNCRDEFECTTYPECODES.NCRID
    LEFT OUTER JOIN dbo.TQMPlantTable ON TQMPlantTable.PlantID  = dbo.TQMNCR.PlantID
    LEFT OUTER JOIN dbo.INVENTTABLE ON dbo.TQMNCR.ITEMID = dbo.INVENTTABLE.ITEMID 
    LEFT OUTER JOIN dbo.INVENTTABLEMODULE ON dbo.INVENTTABLE.ITEMID = dbo.INVENTTABLEMODULE.ITEMID AND MODULETYPE = 2 
    LEFT OUTER JOIN dbo.SALESLINE ON dbo.SALESLINE.SALESID = dbo.TQMNCR.SALESID AND dbo.SALESLINE.ITEMID = dbo.TQMNCR.ITEMID 
    LEFT OUTER JOIN dbo.PRODTABLE ON dbo.TQMNCR.PRODID = dbo.PRODTABLE.PRODID
    inner join sched on sched.itemGroup = INVENTTABLE.itemgroupid
    inner join salesQty on salesQty.itemGroup = INVENTTABLE.itemgroupid
    inner join (
        select itemgroup, SUM(sales$) as 'sales Dollars'
        from salesDollars
    ) salesDollars on  salesDollars.itemgroup = INVENTTABLE.itemgroupid
    LEFT JOIN [MiscReportTables].[dbo].[FiscalCalendar] fc on SCHEDDATE between fc.StartDate and fc.EndDate
    left JOIN INVENTITEMGROUP IG on dbo.INVENTTABLE.ITEMGROUPID = IG.ITEMGROUPID
    LEFT JOIN Pmf_HighLevelItemGrouping HG on IG.HIGHLEVELITEM = HG.HighLevelItemGroupingCode
WHERE
    SCHEDDATE between @start1 and @end1
    AND dbo.TQMNCR.PlantID IN (
        SELECT [PLANTID]
        FROM [Dynamics].[dbo].[TQMPLANTTABLE]
    )