2016-11-17 18 views
1

能否请你帮我提高了表值函数:提高表值函数性能

Create Function [dbo].[xxx](@InvoiceId numeric(18 ,0) ,@InvoiceType int ,@ReceiptAccOwner int) 
    Returns Table 
    As 
    Return(


    Select * From(

      Select N'InvoiceReceiptNo' + Cast(ROW_NUMBER() over(order by ir.ReceiptRecID) as nvarchar(10)) As row 

       ,ir.StockHoldingInvoiceID As InvoiceId 

       ,ir.ReceiptNo As ReceiptValue 
       ,ir.ReceiptAccOwner 
      from InvoiceReceipt As ir  
      Where ir.ReceiptAccOwner = @ReceiptAccOwner 
      And (
        (ir.StockHoldingInvoiceID = @InvoiceId And @InvoiceType in(1 ,6 ,8)) 
       or(ir.THCInvoiceID = @InvoiceId And @InvoiceType = 2) 
       or(ir.EvaluatInvoiceID = @InvoiceId And @InvoiceType = 3) 
       or(ir.StripInvoiceID = @InvoiceId And @InvoiceType = 4) 
       or(ir.EvaluationExportInvoiceID = @InvoiceId And @InvoiceType = 5) 
       or(ir.ServiceInvoiceID = @InvoiceId And @InvoiceType = 7) 
       or(ir.MovementInvoiceId = @InvoiceId And @InvoiceType = 10) 
       or(ir.InterchangeReplicaInvoice = @InvoiceId And @InvoiceType = 11) 
       or(ir.MovementInvoiceId = @InvoiceId And @InvoiceType = 12) 
       or(ir.BLConsigneeChangeRequestInvoiceID = @InvoiceId And @InvoiceType = 15) 
       ) 

      UNION All 

      Select N'InvoiceReceiptPrice' + Cast(ROW_NUMBER() over(order by ir.ReceiptRecID) as nvarchar(10)) As row 

       ,ir.StockHoldingInvoiceID 

       ,Cast(IsNull(ir.ReceiptPrice ,0) as nvarchar(20)) As ReceiptValue 
       ,ir.ReceiptAccOwner 
      from InvoiceReceipt As ir 
      Where ir.ReceiptAccOwner = @ReceiptAccOwner 
      And (
        (ir.StockHoldingInvoiceID = @InvoiceId And @InvoiceType in(1 ,6 ,8)) 
       or(ir.THCInvoiceID = @InvoiceId And @InvoiceType = 2) 
       or(ir.EvaluatInvoiceID = @InvoiceId And @InvoiceType = 3) 
       or(ir.StripInvoiceID = @InvoiceId And @InvoiceType = 4) 
       or(ir.EvaluationExportInvoiceID = @InvoiceId And @InvoiceType = 5) 
       or(ir.ServiceInvoiceID = @InvoiceId And @InvoiceType = 7) 
       or(ir.MovementInvoiceId = @InvoiceId And @InvoiceType = 10) 
       or(ir.InterchangeReplicaInvoice = @InvoiceId And @InvoiceType = 11) 
       or(ir.MovementInvoiceId = @InvoiceId And @InvoiceType = 12) 
       or(ir.BLConsigneeChangeRequestInvoiceID = @InvoiceId And @InvoiceType = 15) 
       ) 

    ) As tb 
    pivot(
      Max(ReceiptValue) --,Sum(ReceiptPrice) 
      For row in ([InvoiceReceiptNo1] ,[InvoiceReceiptNo2] ,[InvoiceReceiptNo3] ,[InvoiceReceiptNo4] ,[InvoiceReceiptNo5] ,[InvoiceReceiptNo6] 
         ,[InvoiceReceiptPrice1] ,[InvoiceReceiptPrice2] ,[InvoiceReceiptPrice3] ,[InvoiceReceiptPrice4] ,[InvoiceReceiptPrice5] ,[InvoiceReceiptPrice6]) 
     ) piv 


    ) 

我在存储过程中使用该功能外适用于SELECT语句, 这个功能应该只返回一个记录每张发票。

XML执行计划: 从[DBO]选择* [fn_GetInvoiceReceiptInfo](149735,1,1) https://anotepad.com/notes/wh34ey

+0

你可以把执行计划放在pastetheplan.com并给我们一个链接?这将帮助我们看到发生了什么。 –

+0

@RichBenner pastetheplan.com不能为我开放。 – Iraj

+0

尝试此链接https://www.brentozar.com/pastetheplan/ –

回答

1

好吧,看看你提供的执行计划,你正在做Key Lookups这意味着你可以调整索引来减少执行时间。

目前,您使用表InvoiceReceipt上的索引Relationship_82_FK返回ReceiptRecIDStockHoldingInvoiceID这两个值。现在,因为此索引不包含您需要的所有信息,SQL必须返回并查看您的聚集索引以返回附加信息。尝试更改索引Relationship_82_FK,将ReceiptAccHolderReceiptPrice作为包含字段。

2

答案取决于你所拥有的索引。除非您具体说明您拥有哪些索引和使用哪些索引,否则很难提出更好的解决方案。

例如,您有一个聚合窗口函数,可以通过更改聚类索引或为特定查询添加覆盖索引来加快速度。但是,如果这真的是瓶颈,那只有意义。

执行计划说什么?

您可能想要尝试的另一件事是在WHERE子句中重写所有没有OR的查询,并且对所有查询使用UNION ALL。这将允许数据库并行化您的查询。

再次,这些东西,你可以尝试,但他们是否工作取决于索引和查询计划的瓶颈。