SQL Server SQL Where clause performance constant vs variable

kognpnkq  于 2023-03-07  发布在  其他
关注(0)|答案(1)|浏览(170)

I have a table function as show below. When I call the function with a literal it completes in 3 seconds on my dataset. So the following completes in 3 seconds:

Select *
from getActiveConcessionsForShipment(12)

If I use a variable, on the other hand, the function completes in 11:32! So the following completes in 11:32s

Declare @shipmentID int = 12
Select *
from getActiveConcessionsForShipment((@shipmentID))

Same function. How can I improve it using a variable? Here is the function:

Alter Function getActiveConcessionsForShipment(@shipmentID int)
returns Table
With Encryption
As
    return 
        (
            -- Item Concessions
            Select 0 OrderNo, ConcessionID, ic.TariffNo, ic.DepartmentID, d.DepartmentName, [Level], i.ItemID, ExpiryDate, GeneralRate Rate, GeneralRateNumeric ConcessionRate, Cast(1 as Bit) Concession
            from Shipment s
            join Manifest m
            on (m.ManifestID = s.ManifestID)
            join ShipmentInvoice si
            on (si.ShipmentID = s.ShipmentID)
            join ShipmentInvoiceDetail sid
            on (sid.ShipmentInvoiceID = si.ShipmentInvoiceID)
            join StockInvoice sti
            on (sti.StockInvoiceID = si.StockInvoiceID)
            join StockInvoiceDetail stid
            on (stid.StockInvoiceDetailID = sid.StockInvoiceDetailID)
            join ItemSupplier isup
            on (isup.SupplierID = sti.SupplierID and isup.SupplierItemNo = stid.SupplierItemNo)
            join Item i
            on (i.ItemID = isup.ItemID)
            join Tariff t
            on (t.TariffID = i.TariffID)
            join Department d
            on (d.DepartmentID = sti.DepartmentID)
            join ItemConcession ic
            on (ic.ItemID = i.ItemID and ic.TariffNo = t.TariffNo)
            Where s.ShipmentID = @shipmentID and ExpiryDate > m.ArrivalDate and 'Paid|Concession|Mixed' like '%' + s.EntryType + '%'

            UNION

            -- Tariff Concessions minus duty paid items
            Select 1, ConcessionID, tc.TariffNo, tc.DepartmentID, d.DepartmentName, [Level], i.ItemID, ExpiryDate, GeneralRate Rate, GeneralRateNumeric ConcessionRate, 1 Concession
            from Shipment s
            join Manifest m
            on (m.ManifestID = s.ManifestID)
            join ShipmentInvoice si
            on (si.ShipmentID = s.ShipmentID)
            join ShipmentInvoiceDetail sid
            on (sid.ShipmentInvoiceID = si.ShipmentInvoiceID)
            join StockInvoice sti
            on (sti.StockInvoiceID = si.StockInvoiceID)
            join StockInvoiceDetail stid
            on (stid.StockInvoiceDetailID = sid.StockInvoiceDetailID)
            join ItemSupplier isup
            on (isup.SupplierID = sti.SupplierID and isup.SupplierItemNo = stid.SupplierItemNo)
            join Item i
            on (i.ItemID = isup.ItemID)
            join Tariff t
            on (t.TariffID = i.TariffID)
            join Department d
            on (d.DepartmentID = sti.DepartmentID)
            join TariffConcession tc
            on (tc.DepartmentID = d.DepartmentID and tc.TariffID = i.TariffID)
            outer apply
            (
            Select StockInvoiceDetailID 
                from FreezoneDutyPaidItem
                Where StockInvoiceDetailID = sid.StockInvoiceDetailID
            ) dpi
            Where s.ShipmentID = @shipmentID and ExpiryDate > m.ArrivalDate and 'Paid|Concession|Mixed' like '%' + s.EntryType + '%' and dpi.StockInvoiceDetailID is null

            UNION

            -- Department Concessions minus duty paid items
            Select 2 [Order], ConcessionID, dc.TariffNo, dc.DepartmentID, d.DepartmentName, [Level], i.itemID, ExpiryDate, GeneralRate Rate, GeneralRateNumeric ConcessionRate, 1 Concession
            from Shipment s
            join Manifest m
            on (m.ManifestID = s.ManifestID)
            join ShipmentInvoice si
            on (si.ShipmentID = s.ShipmentID)
            join ShipmentInvoiceDetail sid
            on (sid.ShipmentInvoiceID = si.ShipmentInvoiceID)
            join StockInvoice sti
            on (sti.StockInvoiceID = si.StockInvoiceID)
            join StockInvoiceDetail stid
            on (stid.StockInvoiceDetailID = sid.StockInvoiceDetailID)
            join ItemSupplier isup
            on (isup.SupplierID = sti.SupplierID and isup.SupplierItemNo = stid.SupplierItemNo)
            join Item i
            on (i.ItemID = isup.ItemID)
            join Tariff t
            on (t.TariffID = i.TariffID)
            join Department d
            on (d.DepartmentID = sti.DepartmentID)
            join DepartmentConcession dc
            on (dc.DepartmentID = d.DepartmentID)
            outer apply
            (
            Select StockInvoiceDetailID 
                from FreezoneDutyPaidItem
                Where StockInvoiceDetailID = sid.StockInvoiceDetailID
            ) dpi
            Where s.ShipmentID = @shipmentID and ExpiryDate > m.ArrivalDate and 'Paid|Concession|Mixed' like '%' + s.EntryType + '%' and dpi.StockInvoiceDetailID is null

            UNION

            -- Bonded in PaidZone
            Select 3 [Order], ConcessionID, dc.TariffNo, dc.DepartmentID, d.DepartmentName, [Level], i.itemID, ExpiryDate, 'Free' Rate, 0 ConcessionRate, 1 Concession
            from Shipment s
            join Manifest m
            on (m.ManifestID = s.ManifestID)
            join ShipmentInvoice si
            on (si.ShipmentID = s.ShipmentID)
            join ShipmentInvoiceDetail sid
            on (sid.ShipmentInvoiceID = si.ShipmentInvoiceID)
            join StockInvoice sti
            on (sti.StockInvoiceID = si.StockInvoiceID)
            join StockInvoiceDetail stid
            on (stid.StockInvoiceDetailID = sid.StockInvoiceDetailID)
            join ItemSupplier isup
            on (isup.SupplierID = sti.SupplierID and isup.SupplierItemNo = stid.SupplierItemNo)
            join Item i
            on (i.ItemID = isup.ItemID)
            join Tariff t
            on (t.TariffID = i.TariffID)
            join Department d
            on (d.DepartmentID = sti.DepartmentID)
            join DepartmentConcession dc
            on (dc.DepartmentID = d.DepartmentID)
            Where s.ShipmentID = @shipmentID and dc.TariffNo = 'Bonded' and s.EntryType = dc.EntryType

            UNION

            -- Freezone Items
            Select 3 [Order], -1 ConcessionID, 'Freezone' TariffNo, d.DepartmentID, DepartmentName, 'Department' [Level], i.ItemID, null ExpiryDate, 'Freezone' Rate, 0 ConcessionRate, 1 Concession
            from Shipment s
            join Manifest m
            on (m.ManifestID = s.ManifestID)
            join ShipmentInvoice si
            on (si.ShipmentID = s.ShipmentID)
            join ShipmentInvoiceDetail sid
            on (sid.ShipmentInvoiceID = si.ShipmentInvoiceID)
            join StockInvoice sti
            on (sti.StockInvoiceID = si.StockInvoiceID)
            join StockInvoiceDetail stid
            on (stid.StockInvoiceDetailID = sid.StockInvoiceDetailID)
            join ItemSupplier isup
            on (isup.SupplierID = sti.SupplierID and isup.SupplierItemNo = stid.SupplierItemNo)
            join Item i
            on (i.ItemID = isup.ItemID)
            join Tariff t
            on (t.TariffID = i.TariffID)
            join Department d
            on (d.DepartmentID = sti.DepartmentID)
            outer apply
            (
            Select StockInvoiceDetailID 
                from FreezoneDutyPaidItem
                Where StockInvoiceDetailID = sid.StockInvoiceDetailID
            ) dpi
            Where s.ShipmentID = @ShipmentID and EntryType = 'Freezone' and dpi.StockInvoiceDetailID is null
            
        )
go
8yoxcaq7

8yoxcaq71#

I appreciate all of the comments. It occurred to me that passing a table field would solve my issue, so I tried it and execute completed in 1s. My last issue was to do the same without using a permanent table, so I Googled around and came up with the following:

CREATE TYPE TableType 
AS TABLE (ShipmentID int not null)
GO 

DECLARE @SelectedShipmentTable TableType
INSERT INTO @SelectedShipmentTable(ShipmentID) VALUES(12)

Select *
from getActiveConcessionsForShipment((SELECT ShipmentID FROM @SelectedShipmentTable))

相关问题