2016-11-17 47 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。這將允許數據庫並行化您的查詢。

再次,這些東西,你可以嘗試,但他們是否工作取決於索引和查詢計劃的瓶頸。