1


1

私はSQL Server 2005でこのクエリを持っています:

SELECT J.JobID、dbo.tblCustomers.Name AS CustomerName、J.CustomerJobNumber、J.JobName、([WHEN [tblCustomers]。[CoreCust] = 0の場合] [AUXILIARY]、[ELSE]、[CORE]、END)AS Department、J.JobStatusID、 dbo.tblJobTypes.JobType from dbo.tblJobs(NOLOCK)AS J内部結合dbo.tblCustomers(NOLOCK)ON J.CustomerID = dbo.tblCustomers.CustomerID内部結合dbo.tblJobTypes(NOLOCK)on J.JobTypeID = dbo.tblJobType内部dbo.tblDepartments(NOLOCK)on J.DepartmentId = dbo.tblDepartments.DepartmentID WHERE(J.Closed = 0)AND(J.Invoiced = 0)AND(J.Active = 1)AND(dbo.fncIsAllPointsDelivered(J。 JobID)= 1)AND(J.DepartmentId <> 2)

このクエリは実行するのに時間がかかりすぎています、そして私は問題がUDFであることを知っています - (dbo.fncIsAllPointsDelivered(J.JobID)= 1) -

UDFのSQLは次のとおりです。

DECLARE @DetailCount int DECLARE @TrackingCount int

SELECT @DetailCount = COUNT(*)from [dbo]。[tblLoadDetails](NOLOCK)WHERE JobId = @JobId

SELECT @TrackingCount = COUNT(*)[dbo]。[tblLoadDetails](NOLOCK)WHERE JobId = @JobId AND Delivered = 1

IF(@DetailCount = @TrackingCount AND @DetailCount> 0)戻り値1

戻る0

ジョブに大量の負荷詳細が含まれていない限り、これらすべては非常に高速に実行されます。 UDFを高速化するか、UDFの必要性を排除する方法を検討しようとしていますが、私は迷っています。 私はあなたの何人かのSQLの達人が私を助けてくれることを望んでいます。

2 回答


5


SELECT  *
FROM    tblJobs j
INNER JOIN
        tblCustomers c
ON      c.CustomerID = J.CustomerID
INNER JOIN
        tblJobTypes jt
ON      jt.JobTypeID = J.JobTypeID
INNER JOIN
        tblDepartments d
ON      d.DepartmentID = J.DepartmentId
WHERE   J.Closed = 0
        AND J.Invoiced = 0
        AND J.Active = 1
        AND J.DepartmentId <> 2
        AND J.JobID IN
        (
        SELECT  JobID
        FROM    tblLoadDetails
        )
        AND J.JobID NOT IN
        (
        SELECT  JobID
        FROM    tblLoadDetails
        WHERE   Delivered <> 1
        )

これらのフィールドに複合インデックスを作成します。

tblJobs (Closed, Invoiced, Active) INCLUDE (DepartmentID)

`+ tblLoadDetails.Delivered +`がビットフィールドの場合、次のインデックスを作成します。

tblLoadDetail (JobID, Delivered)

そして最後の条件を次のように書き換えます。

SELECT  *
FROM    tblJobs j
INNER JOIN
        tblCustomers c
ON      c.CustomerID = J.CustomerID
INNER JOIN
        tblJobTypes jt
ON      jt.JobTypeID = J.JobTypeID
INNER JOIN
        tblDepartments d
ON      d.DepartmentID = J.DepartmentId
WHERE   J.Closed = 0
        AND J.Invoiced = 0
        AND J.Active = 1
        AND J.DepartmentId <> 2
        AND
        (
        SELECT  TOP 1 Delivered
        FROM    tblLoadDetails ld
        WHERE   ld.JobID = j.JobID
        ORDER BY
                Delivered
        ) = 1


1


私は頭の上から作業しているので、試していません。 しかし、私はあなたが機能を削除するためにこれを行うことができると思います。 関数の呼び出しをこれら2つの句に置き換えます。 これは 'Delivered’がBITフィールドであると仮定しています。

AND EXISTS (SELECT 1 FROM tblLoadDetails WHERE JobID = J.JobID)
AND NOT EXISTS (SELECT 1 FROM tblLoadDetails WHERE JobID = J.JobID AND Delivered = 0)

「+ AND EXISTS 」は、UDFの「 @ DetailCount> 0+」チェックをカバーします。次に、「+ AND NOT EXISTS 」は@ ` DetailCount = @ TrackingCount +`をカバーします。私が下すのは、ジョブが存在し、そのジョブに関連するすべてが配信されたかどうかを確認することです。 そのため、まだ配信されていないものが1つでもある場合は、除外する必要があります。

述べたように:頭の上から、したがってテストもプロファイルもされていません。 論理は正しいと思います。 そうでなければ、それはその単純な変形であるべきです。