我目前正在Delphi開發一個應用程序,它使用SQL來挖掘第三方開票系統的後端,因此我們可以擴展它的報告功能。我認爲自己在編程的delphi方面相當精通,但SQL對我來說是新的,所以在這個論壇和其他資源的巨大幫助下,我設法教會了自己,而不是我認爲我能夠做到的。複雜查詢 - 連接會比子查詢更快嗎?
大部分數據都是從幾張表中抽出來的(我沒有這方面的問題,所以我不會阻塞那些細節的帖子),但是我有一個問題得到的成本價格。它存儲在一個表中,可以跟蹤每個產品的歷史成本價格(16'000+),可能有數百條記錄,但是我只需要每張產品與發票日期最接近的成本(< =) 。 下面是函數:
CREATE FUNCTION dbo.CostAtDate (@costdate AS datetime , @product AS int)
RETURNS decimal(18,2)
AS
BEGIN
DECLARE @result decimal(18,2)
SET @result = (
Select Top 1
BASE_InventoryCostLogDetail.AverageCostAfter
From
BASE_InventoryCostLogDetail
Where
CreatedDttm < @costdate And CreatedDttm > DATEADD(month,-1,@costDate) And
ProdId = @product
Order By
CreatedDttm Desc)
RETURN @result
END
這裏是查詢之一(有幾個不同的,但都在同一基本結構爲基礎):
Select
BASE_Customer.Name,
SO_SalesOrder.OrderNumber,
SO_SalesOrderInvoice_Line.Description,
SO_SalesOrderInvoice_Line.UnitPrice,
Case SO_SalesOrderInvoice_Line.ItemTaxCodeId
When '100' Then (SO_SalesOrderInvoice_Line.UnitPrice/11) * 10
Else SO_SalesOrderInvoice_Line.UnitPrice End As exgst,
SO_SalesOrderInvoice_Line.QuantityUom,
SO_SalesOrderInvoice_Line.QuantityDisplay,
Case SO_SalesOrderInvoice_Line.QuantityUom
When 'cases.' Then dbo.CostAtDate(SO_SalesOrder.OrderDate,
SO_SalesOrderInvoice_Line.ProdId) * BASE_Product.SoUomRatioStd
Else dbo.CostAtDate(SO_SalesOrder.OrderDate,
SO_SalesOrderInvoice_Line.ProdId) End As cost,
Case SO_SalesOrderInvoice_Line.QuantityUom
When 'cases.' Then ((dbo.CostAtDate(SO_SalesOrder.OrderDate,
SO_SalesOrderInvoice_Line.ProdId) * BASE_Product.SoUomRatioStd)/11) * 10
Else (dbo.CostAtDate(SO_SalesOrder.OrderDate,
SO_SalesOrderInvoice_Line.ProdId)/11) * 10 End As exgstcost,
BASE_Product.SoUomRatioStd,
BASE_Product.Name As Name1,
SO_SalesOrder.OrderDate
From
BASE_Customer Inner Join
SO_SalesOrder On SO_SalesOrder.CustomerId = BASE_Customer.CustomerId
Inner Join
SO_SalesOrderInvoice_Line On SO_SalesOrderInvoice_Line.SalesOrderId =
SO_SalesOrder.SalesOrderId Inner Join
BASE_Product On SO_SalesOrderInvoice_Line.ProdId = BASE_Product.ProdId
Where
SO_SalesOrder.OrderDate Between '20131028' And '20131029'
現在能正常工作時,我只在選定範圍內有幾張發票,但考慮到它每個記錄至少要調用三次函數,當我在超過一天的時間內生成報告時,性能會降低(我們通常需要報告兩週時間)。
不幸的是,鑑於它是第三方產品(任何人誰好奇inFlow庫存),我不能改變表結構。
是否有任何方式使用更高效的聯接,派生表(我理解這個概念,但從來沒有這樣做過),甚至重寫整個查詢,這將大大提高性能?
sqlfiddle ...... –
如果從查詢中刪除函數,性能是否會顯着不同? – Andrew
@Andrew如果我刪除函數並將其替換爲無,那麼是的它是非常快的(172毫秒沒有功能,11.03秒的功能)。但是,如果我將函數替換爲該函數有效地執行的子查詢,那麼執行時間將回落到幾十秒。 –