-3

以下の sql クエリを高速化するにはどうすればよいですか。23 レコードだけで 13 秒かかるからです。テーブル変数の代わりに既に一時テーブルを使用していますが、あまり良くありません。他の結合を使用したり、条件を 2 つの部分に分割したりできますか、それともインデックス作成の問題ですか?

   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 に答える