存储过程优化

时间:2016-07-15 08:33:26

标签: sql sql-server tsql stored-procedures

我编写了以下SQL存储过程,并且因为所有选择命令(我认为)现在运行速度非常慢,所以数据库已经填充了大量数据。有没有办法优化它,以便它运行得更快?目前在Azure S0 DB中,处理大约需要1:40分钟。这是存储过程:

USE [cmb2SQL]
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[spStockReport] @StockReportId as INT
AS
    select 
        ProductId, 
        QtyCounted, 
        LastStockCount, 
        Purchases, 
        UnitRetailPrice, 
        CostPrice, 
        GrossProfit, 
        Consumed,
        (Consumed * UnitRetailPrice) as ValueOfSales,
        (QtyCounted * CostPrice) as StockOnHand, 
        StockCountId
    from (
        select 
            ProductId, 
            QtyCounted, 
            LastStockCount, 
            Purchases, 
            UnitRetailPrice, 
            CostPrice, 
            GrossProfit, 
            (LastStockCount + Purchases) - QtyCounted as Consumed,
            StockCountId
        from (
            select
                distinct
                sci.StockCountItem_Product as ProductId,  
                (Select ISNULL(SUM(Qty), 0) as tmpQty from 
                    (Select Qty from stockcountitems
                    join stockcounts on stockcountitems.stockcountitem_stockcount = stockcounts.id
                    where stockcountitem_Product = p.Id and stockcountitem_stockcount = sc.id and stockcounts.stockcount_pub = sc.StockCount_Pub
                    ) as data
                ) as QtyCounted,
                (Select ISNULL(SUM(Qty), 0) as LastStockCount from 
                    (Select Qty from StockCountItems as sci
                        join StockCounts on sci.StockCountItem_StockCount = StockCounts.Id
                        join Products on sci.StockCountItem_Product = Products.id
                    where sci.StockCountItem_Product = p.id and sci.stockcountitem_stockcount =
                        (select top 1 stockcounts.id from stockcounts
                        join stockcountitems on stockcounts.id = stockcountitem_stockcount
                        where stockcountitems.stockcountitem_product = p.id and stockcounts.id < sc.id  and StockCounts.StockCount_Pub = sc.StockCount_Pub
                        order by stockcounts.id desc)
                    ) as data
                ) as LastStockCount,
                (Select ISNULL(SUM(Qty * CaseSize), 0) as Purchased from
                    (select Qty, Products.CaseSize from StockPurchaseItems
                        join Products on stockpurchaseitems.stockpurchaseitem_product = products.id
                        join StockPurchases on stockpurchaseitem_stockpurchase = stockpurchases.id
                        join Periods on stockpurchases.stockpurchase_period = periods.id
                    where Products.id = p.Id and StockPurchases.StockPurchase_Period = sc.StockCount_Period and StockPurchases.StockPurchase_Pub = sc.StockCount_Pub) as data
                ) as Purchases,
                sci.RetailPrice as UnitRetailPrice,
                sci.CostPrice,
                (select top 1 GrossProfit from Pub_Products where Pub_Products.Pub_Product_Product = p.id and Pub_Products.Pub_Product_Pub = sc.StockCount_Pub) as GrossProfit,
                sc.Id as StockCountId
            from StockCountItems as sci 
                join StockCounts as sc on sci.StockCountItem_StockCount = sc.Id
                join Pubs on sc.StockCount_Pub = pubs.Id
                join Periods as pd on sc.StockCount_Period = pd.Id
                join Products as p on sci.StockCountItem_Product = p.Id
                join Pub_Products as pp on p.Id = pp.Pub_Product_Product
            Where StockCountItem_StockCount = @StockReportId  and pp.Pub_Product_Pub = sc.StockCount_Pub
            Group By sci.CostPrice, sci.StockCountItem_Product, sci.Qty, sc.Id, p.Id, sc.StockCount_Period, pd.Id, sci.RetailPrice, pp.CountPrice, sc.StockCount_Pub
        ) as data
    ) as final

GO

这里要求的是XML格式的执行计划(必须将其上传到tinyupload,因为它超过了消息字符长度):

execusionplan.xml

架构:

Table Schema

行计数:

Table   row_count
StockPurchaseItems  57511
Products    3116
StockCountItems 60949
StockPurchases  6494
StockCounts 240
Periods 30
Pub_Products    5694
Pubs    7

1 个答案:

答案 0 :(得分:0)

不进入查询重写,它是最昂贵的,也是你应该做的最后一件事。首先逐个尝试这些步骤,并测量影响 - 时间,执行计划和SET STATISTICS IO ON输出。首先为这些指标创建基线。当你达到可接受的表现时停止。

首先,更新相关表格的统计数据,我看到一些估计值已经过时了。检查执行计划的估计与实际行 - 现在更好吗?

在StockPurchaseItems(StockPurchaseItem_Product)和StockCountItems(StockCountItem_Product,StockCountItem_StockCount)上创建索引。检查执行计划,优化器是否考虑使用索引?

向这两个索引添加(包括)其他引用的列以覆盖查询。它们现在用完了吗?

如果上述内容没有任何帮助,请考虑将查询分解为较小的查询。很高兴有一些真实的数据可以更具体地进行试验。

**&#34;选择不同的&#34;闻起来很糟糕,你确定连接都没关系吗?