-3

我怎样才能加快下面的 sql 查询,因为它只需要 13 秒来处理 23 条记录。已经使用临时表而不是表变量,但不是很好。我可以使用其他一些联接或将条件分成两部分还是索引问题?

   INSERT INTO #Fulfill (
    [ordergroup_id]
    ,[lineitem_id]
    ,[CreateDate]
    ,[CreateTime]
    ,[UserID]
    ,[CreatedBy]
    ,[Model]
    ,[Year]
    ,[SKU]
    ,[Manufacturer]
    ,[ProductName]
    ,[OrderReference]
    ,[Status]
    ,[NetworkPO]
    ,[TrackingNo]
    ,[ShippingNote]
    ,[CarrierName]
    ,[TrackingURL]
    ,[PartCost]
    ,[EstShipping]
    ,[DMSPONo]
    ,[PODate]
    ,[Vendor]
    ,[d_DateCreated]
    ,[StatusCode]
    ,[LocationOrderCutoff]
    ,[ReleasedDate]
    ,[Source]
    ,[Make]
    ,[Submodel]
    ,[RejectedReason]
    ,[ProductID]
    ,[OrderedFor]
    ,[Customer Business Card]
    ,[LeadStoreID]
    ,[ScheduledInstallDate]
    ,[InstallCompleteDate]
    ,[RONumber]
    ,[VIN]
    ,[LeadSource]
    ,[StoreADICount]
    )
SELECT OFLI.ordergroup_id
    ,OFLI.lineitem_id
    ,convert(VARCHAR(10), OFLI.d_DateCreated, 101) [CreateDate]
    ,SUBSTRING(convert(VARCHAR(20), OFLI.d_DateCreated, 100), 13, 7) [CreateTime]
    ,CASE ISNULL(CONVERT(VARCHAR(50), OFH.SalespersonID), '')
        WHEN ''
            THEN OFH.user_id
        ELSE OFH.SalespersonID
        END [UserID]
    ,ISNULL(UO.firstname, '') + ' ' + ISNULL(UO.lastname, '') [CreatedBy]
    ,OFH.Model [Model]
    ,OFH.VehicleYear [Year]
    ,ACI.SKU
    ,AB.BrandDescription [Manufacturer]
    ,ACI.Caption [ProductName]
    ,OFH.OrderReference
    ,ISNULL(CASE isnull(OFLI.PurchaseOrderRef, '')
            WHEN ''
                THEN 'Pending'
            ELSE isNull(AGSM.CustomStatusDesc, S.StatusDescription)
            END, ' ') [Status]
    ,SUBSTRING(OFLI.PurchaseOrderRef, 0, PATINDEX('%.%', OFLI.PurchaseOrderRef)) [NetworkPO]
    ,POLI.TrackingNo
    ,POLI.ShippingNote
    ,C.CarrierName
    ,C.TrackingURL
    ,POLI.UnitCost AS [PartCost]
    ,POLI.EstShipping AS [EstShipping]
    ,PO.DMSPONo
    ,convert(VARCHAR(10), PO.ReleaseDate, 101) [PODate]
    ,CASE 
        WHEN SP.SupplierID IS NULL
            THEN SRC.SourceName
        ELSE SP.SupplierName
        END [Vendor]
    ,OFLI.d_DateCreated
    ,CASE isnull(OFLI.PurchaseOrderRef, '')
        WHEN ''
            THEN 0
        ELSE ISNULL(POLI.StatusCode, 1)
        END [StatusCode]
    ,isNull(SPL.LocationOrderCutoff, '00:00') [LocationOrderCutoff]
    ,PO.ReleaseDate AS ReleasedDate
    ,0 [Source]
    ,OFH.Make AS [Make]
    ,OFH.Trim AS [Submodel]
    ,ISNULL(POLI.RejectedReason, '') [RejectedReason]
    ,OFLI.product_id [ProductID]
    ,OFH.OrderedFor AS OrderedFor
    ,NULL AS [Customer Business Card]
    ,OFH.user_org_name AS [LeadStoreID]
    ,OFLI.ScheduledInstallDate
    ,OFLI.InstallCompleteDate
    ,OFLI.RONumber
    ,OFH.VIN
    ,OFH.LeadSource
    ,dbo.ASM_GetADIInventoryCount(OFLI.product_id, '', '', @StoreID, 0)
FROM OrderFormLineItems OFLI(NOLOCK)
INNER JOIN OrderFormHeader OFH(NOLOCK) ON OFLI.ordergroup_id = OFH.ordergroup_id
INNER JOIN OrderGroup OG(NOLOCK) ON OFLI.ordergroup_id = OG.ordergroup_id
    AND OG.order_status_code IN (
        4
        ,8
        )
INNER JOIN CATALOG.dbo.ASMCatalogItems ACI(NOLOCK) ON ACI.ItemID = OFLI.product_id
INNER JOIN CATALOG.dbo.ASMBrands AB(NOLOCK) ON AB.BrandCode = ACI.BrandCode
INNER JOIN UserObject UO(NOLOCK) ON UO.g_id = (
        CASE ISNULL(CONVERT(VARCHAR(50), OFH.SalespersonID), '')
            WHEN ''
                THEN OFH.user_id
            ELSE OFH.SalespersonID
            END
        )
LEFT JOIN ASMPurchaseOrder PO(NOLOCK) ON PO.PONumber = SUBSTRING(OFLI.PurchaseOrderRef, 0, PATINDEX('%.%', OFLI.PurchaseOrderRef))
LEFT JOIN ASMPurchaseOrderLineItemDetails POLI(NOLOCK) ON PO.PONumber = POLI.PONumber
    AND OFLI.PurchaseOrderRef = CONVERT(VARCHAR, POLI.PONumber) + '.' + CONVERT(VARCHAR, POLI.POLineItemNo)
LEFT JOIN ASMStatus S(NOLOCK) ON S.StatusType = 'POLI'
    AND S.StatusCode = POLI.StatusCode
LEFT JOIN ASMGroupStatusMapping AGSM(NOLOCK) ON S.StatusCode = AGSM.StatusCode
    AND AGSM.StatusTypeID = 2
    AND AGSM.GroupID = @GroupID
LEFT JOIN ASMCarriers C(NOLOCK) ON C.CarrierID = POLI.CarrierID
LEFT JOIN ASMSupplierLocations SPL(NOLOCK) ON SPL.SupplierLocationID = PO.SupplierLocationID
LEFT JOIN ASMSuppliers SP(NOLOCK) ON SP.SupplierID = SPL.SupplierID
LEFT JOIN ASMSource SRC(NOLOCK) ON PO.SourceID = SRC.SourceID
LEFT JOIN UserObject UO2(NOLOCK) ON OFH.OrderedFor = UO2.g_id
WHERE OFLI.line_Item_Status_Code <> 4
    AND OFH.OrderReference > ''
    AND (
        @DMSPONo = ''
        OR @DMSPONo = PO.DMSPONo
        )
    AND (
        POLI.PONumber = @NetworkPO
        OR @NetworkPO IS NULL
        )
    AND (
        @VendorName = ''
        OR SP.SupplierName LIKE '%' + @VendorName + '%'
        )
    AND (
        @CreatedByID IS NULL
        OR OFH.user_id = @CreatedByID
        )
    AND (
        @OrderReference = ''
        OR OFH.OrderReference LIKE '%' + @OrderReference + '%'
        OR UO2.FirstName LIKE '%' + @OrderReference + '%'
        OR UO2.LastName LIKE '%' + @OrderReference + '%'
        OR UO2.Organization LIKE '%' + @OrderReference + '%'
        )
    AND (
        @Keyword = ''
        OR ACI.SKU LIKE '%' + @Keyword + '%'
        OR AB.BrandDescription LIKE '%' + @Keyword + '%'
        OR ACI.Caption LIKE '%' + @Keyword + '%'
        )
    AND (
        @ORDER_DATE_1 IS NULL
        OR @ORDER_DATE_1 = '1/1/1900'
        OR (
            OFLI.d_DateCreated BETWEEN @ORDER_DATE_1
                AND CASE 
                        WHEN @ORDER_DATE_2 IS NULL
                            THEN GETDATE()
                        ELSE @ORDER_DATE_2
                        END
            )
        )
    AND (
        @PO_Date_1 IS NULL
        OR @PO_Date_1 = '1/1/1900'
        OR (
            PO.ReleaseDate BETWEEN @PO_Date_1
                AND CASE 
                        WHEN @PO_Date_2 IS NULL
                            THEN GETDATE()
                        ELSE @PO_Date_2
                        END
            )
        )
    AND (
        @Source = 0
        OR (
            @Source = 1
            AND EXISTS (
                SELECT *
                FROM UserObject UO2(NOLOCK)
                WHERE UO2.G_id = OFH.user_ID
                    AND UO2.UserRole <> 1
                )
            )
        OR (
            @Source = 2
            AND EXISTS (
                SELECT *
                FROM UserObject UO2(NOLOCK)
                WHERE UO2.G_id = OFH.user_ID
                    AND UO2.UserRole = 1
                )
            )
        )
    AND (
        (
            @WithCustomer = 1
            AND @WithoutCustomer = 1
            )
        OR (
            @WithCustomer = 1
            AND @WithoutCustomer = 0
            AND OFH.OrderedFor IS NOT NULL
            )
        OR (
            @WithCustomer = 0
            AND @WithoutCustomer = 1
            AND OFH.OrderedFor IS NULL
            )
        )
    AND OFH.user_org_name = @StoreID --@STOREID_TMP 
    AND OFLI.product_id NOT LIKE '%$%'
    AND OFLI.product_id NOT LIKE '[#]%'
    AND OFLI.product_id NOT LIKE '%(%'
    AND OFLI.product_id NOT LIKE '%*%'
    AND ACI.SKU NOT LIKE 'DTPACKAGE%'
4

2 回答 2

2

是的,SQL 查询有时需要一些时间来执行。

原因:

  • 如果列表中使用的表未使用foreign和组合primary keys
  • 如果查询有多个表并且连接在比较中使用字符串值。(为此,使用数值进行连接是一种很好的做法。)
  • 如果涉及的表没有索引。(索引使 SQL 查询运行得更快。)
  • 还有其他原因会导致 SQL 查询运行缓慢。

我会建议您检查这些内容以了解您的表格描述。

于 2013-05-22T08:48:26.857 回答
0

您应该仅使用活动过滤器动态构建查询,而不是使用“可选”参数。它可能会给你带来巨大的加速。

如果您不能即时建立查询,也许您可​​以制作一组特定于某些参数组合的存储过程。

如果你也不能这样做,那么至少使用查询提示 WITH RECOMPILE。

于 2013-05-22T09:03:55.730 回答