がありUDF
、大量のデータを提供しています。いくつかのテーブル変数が使用されます。この時点では、インデックスは作成されません。
テストデータを使用した実行時間は約30 秒です。
テーブル変数を一時テーブルに変更するだけで (許可されUDF
て#tables
いないため、 以外)、実行時間が大幅に短縮されます。約3秒です。この記事では違いについて説明していますが、この種のパフォーマンス デルタの原因となっているポイントがわかりません。
とにかく、一時テーブルは許可されていないUDF
ので、SPROC
. 残念ながら、データのターゲット「コンテナー」はビューまたはテーブルでなければならないため、できません。サードパーティの制限により変更できません。(erp システムのデータは事前に処理されており、テーブルまたはビューで提供する必要があります。たとえば、select <col> from <object>
.
現在使用しているテーブル変数を作成するインデックスを追加してみましたが、実行時間は減りませんでした。
最後にビューにデータを取得しながら、一時テーブルのパフォーマンスを達成するためのヒントやヒントをいただければ幸いです。
SQL-Query (テーブル変数が追加されますが、デモ データは提供できません):
declare @Results TABLE
(
"id" NVARCHAR( 100 )
, "oprNum1" INT
, "job1Id" NVARCHAR( 100 )
, "job1Type" INT
, "oprNum2" INT
, "job2Id" NVARCHAR( 100 )
, "job2Type" INT
, "minimumDistance" INT
, "maximumDistance" INT
, "resourceLocked" INT
, "durationLocked" INT
, "slot1" FLOAT
, "slot2" FLOAT
, "color" BIGINT
, "origin" NVARCHAR( 50 )
, "partition" BIGINT
)
DECLARE @jobs TABLE
(
"rank" INT
, "id" NVARCHAR( 100 )
, "projectId" NVARCHAR( 100 )
, "prodId" NVARCHAR( 20 )
, "oprNum" INT
, "oprPriority" INT
, "jobId" NVARCHAR( 100 )
, "jobType" INT
, "overlapFactor" FLOAT
, "partition" BIGINT
, UNIQUE CLUSTERED("rank","prodId","jobid")
);
INSERT INTO @jobs
SELECT
"rank" = RANK() OVER ( PARTITION BY job."dataAreaId", job."prodId"
, CASE job."oprPriority"
WHEN 0 THEN job."oprPriority"
ELSE job."oprPriority" / job."oprPriority"
END
ORDER BY job."rank" )
, "id" = job."id"
, "projectId" = job."projectId"
, "prodId" = job."prodId"
, "oprNum" = job."oprNum"
, "oprPriority" = job."oprPriority"
, "jobId" = job."axJobId"
, "jobType" = job."jobType"
, "overlapFactor" = job."overlapFactor"
, "partition" = job."partition"
FROM "dbo"."_company_job" AS job;
INSERT INTO @Results
(
"id"
, "oprNum1"
, "job1Id"
, "job1Type"
, "oprNum2"
, "job2Id"
, "job2Type"
, "minimumDistance"
, "maximumDistance"
, "resourceLocked"
, "durationLocked"
, "slot1"
, "slot2"
, "color"
, "origin"
, "partition"
)
SELECT DISTINCT
"id" = Job1."id" + N'_' + Job2."id"
, "oprNum1" = Job1."oprNum"
, "job1Id" = Job1."id"
, "job1Type" = Job1."jobType"
, "oprNum2" = Job2."oprNum"
, "job2Id" = Job2."id"
, "job2Type" = Job2."jobType"
, "minimumDistance" = 0
, "maximumDistance" = 0
, "resourceLocked" = CASE Job1."oprNum" WHEN Job2."oprNum" THEN 1 ELSE 0 END
, "durationLocked" = 0
, "slot1" = Job1."OVERLAPFACTOR"
, "slot2" = 0.0
, "color" = 0x00FFFFFF
, "origin" = 'job'
, "partition" = Job1."partition"
FROM @jobs AS Job1
INNER JOIN @jobs AS Job2
ON 1 = 1
AND Job2."partition" = Job1."partition"
AND Job2."projectId" = Job1."projectId"
AND Job2."oprPriority" = Job1."oprPriority"
AND Job2."rank" = Job1."rank" +1
AND Job2."id" != Job1."id"
AND Job2.jobType NOT IN ( 4 )
WHERE Job1."oprPriority" = 0
OR ( Job1."oprPriority" > 0 AND Job1."oprNum" = job2."oprNum" );
INSERT INTO @Results
(
"id"
, "oprNum1"
, "job1Id"
, "job1Type"
, "oprNum2"
, "job2Id"
, "job2Type"
, "minimumDistance"
, "maximumDistance"
, "resourceLocked"
, "durationLocked"
, "slot1"
, "slot2"
, "color"
, "origin"
, "partition"
)
SELECT
"id" = Job1."id" + N'_' + Job2."id"
, "oprNum1" = Job1."oprNum"
, "job1Id" = Job1."id"
, "job1Type" = Job1."jobType"
, "oprNum2" = Job2."oprNum"
, "job2Id" = Job2."id"
, "job2Type" = Job2."jobType"
, "minimumDistance" = 0
, "maximumDistance" = 2147483647
, "resourceLocked" = CASE Job1."oprNum" WHEN Job2."oprNum" THEN 1 ELSE 0 END
, "durationLocked" = 0
, "slot1" = job2."OVERLAPFACTOR"
, "slot2" = 0.0
, "color" = 0x000000FF
, "origin" = 'milestone'
, "partition" = Job1."partition"
FROM @jobs AS job1
INNER JOIN @jobs AS job2
ON 1 = 1
AND job2."partition" = job1."partition"
AND job2."projectId" = job1."projectId"
AND Job2."oprPriority" = Job1."oprPriority"
AND Job2."rank" = Job1."rank" +1
AND Job1."id" != Job2."id"
AND Job2.jobType IN ( 4 );
INSERT INTO @Results
(
"id"
, "oprNum1"
, "job1Id"
, "job1Type"
, "oprNum2"
, "job2Id"
, "job2Type"
, "minimumDistance"
, "maximumDistance"
, "resourceLocked"
, "durationLocked"
, "slot1"
, "slot2"
, "color"
, "origin"
, "partition"
)
SELECT
"id" = CASE slot."value"
WHEN 0.0
THEN Job1."id" + N'_' + Job2."id"
ELSE Job2."id" + N'_' + Job1."id"
END
, "oprNum1" = Job1."oprNum"
, "job1Id" = Job1."id"
, "job1Type" = Job1."jobType"
, "oprNum2" = Job2."oprNum"
, "job2Id" = Job2."id"
, "job2Type" = Job2."jobType"
, "minimumDistance" = 0
, "maximumDistance" = 0
, "resourceLocked" = 0
, "durationLocked" = 0
, "slot1" = slot."value"
, "slot2" = slot."value"
, "color" = 0xCCCC00FF
, "origin" = N'job'
, "partition" = Job1."partition"
FROM @jobs AS Job1
INNER JOIN @jobs AS Job2
ON 1 = 1
AND job2."partition" = job1."partition"
and job2."projectId" = job1."projectId"
AND job2."oprNum" = job1."oprNum"
AND job2."jobType" = job1."jobType"
AND Job2."oprPriority" = job1."oprPriority" +1
AND Job2."id" != Job1."id"
LEFT JOIN @jobs AS prevJob
ON 1 = 1
AND prevJob."partition" = job2."partition"
AND prevJob."projectId" = job2."projectId"
AND prevJob."rank" = job2."rank" -1
AND prevJob."oprPriority" = job2."oprPriority"
AND prevJob."id" != job2."id"
INNER JOIN "dbo"."BASEENUMS" AS enums
ON enums."NAME" = N'someName'
AND job1."jobType" = enums."VALUEID"
INNER JOIN (
select 0.0 as "value"
union all
select 1.0
) as slot
ON ( slot."value" = 0 AND ( enums."VALUE" = N'setup' OR ( enums."VALUE" = N'normal' AND prevJob."id" IS NULL ) ) )
OR ( slot."value" = 1 AND enums."VALUE" = N'normal' );
DECLARE @PeggingRelations TABLE
(
"oprNum1" INTEGER
, "job1Id" NVARCHAR( 100 )
, "job1Type" INT
, "oprNum2" INTEGER
, "job2Id" NVARCHAR( 100 )
, "job2Type" INT
, "minimumDistance" INT
, "maximumDistance" INT
, "resourceLocked" INT
, "durationLocked" INT
, "slot1" FLOAT
, "slot2" FLOAT
, "color" INT
, "origin" NVARCHAR(50)
, "partition" BIGINT
);
DECLARE @MinMax TABLE
(
"prodId" NVARCHAR( 20 )
, "maxOprNum" INT
, "minOprNum" INT
);
INSERT INTO @MinMax
SELECT
"prodId" = "prodId"
, "maxOprNum" = MAX( "oprNum" )
, "minOprNum" = MIN( "oprNum" )
FROM
"dbo"."_company_job"
GROUP BY
"prodId";
INSERT INTO @PeggingRelations
SELECT DISTINCT
"oprNum1" = Job1."oprNum"
, "job1Id" = Job1."id"
, "job1Type" = Job1."jobType"
, "oprNum2" = Job2."oprNum"
, "job2Id" = Job2."id"
, "job2Type" = Job2."jobType"
, "minimumDistance" = 0
, "maximumDistance" = 2147483647
, "resourceLocked" = CASE Job1."oprNum" WHEN Job2."oprNum" THEN 1 ELSE 0 END
, "durationLocked" = 0
, "slot1" = job1."OVERLAPFACTOR"
, "slot2" = 0.0
, "color" = 0x0000FFFF
, "origin" = N'workorder'
, "partition" = Job1."partition"
FROM
"dbo"."REQTRANSCOV" AS Link
INNER merge JOIN "dbo"."REQTRANS" AS Issuer
ON Issuer."DATAAREAID" = Link."DATAAREAID"
AND Issuer."PARTITION" = Link."PARTITION"
AND Issuer."RECID" = Link."ISSUERECID"
INNER JOIN "dbo"."REQTRANS" AS Receiver
ON Receiver."DATAAREAID" = Link."DATAAREAID"
AND Receiver."partition" = Link."partition"
AND Receiver."recid" = Link."RECEIPTRECID"
INNER JOIN @MinMax AS IssuerMinOprNum
ON IssuerMinOprNum."PRODID" = Issuer."REFID"
INNER JOIN @MinMax AS ReceiverMaxOprNum
ON ReceiverMaxOprNum."PRODID" = Receiver."REFID"
INNER JOIN "dbo"."_company_job" AS Job2
ON Job2."prodId" = Issuer."REFID"
AND Job2."oprNum" = IssuerMinOprNum."minOprNum"
AND Job2."isFirst" = 1
AND Job2."oprPriority" = 0
AND Job2."partition" = Issuer."partition"
INNER JOIN "dbo"."_company_job" AS Job1
ON Job1."prodId" = Receiver."REFID"
AND Job1."isLast" = 1
AND Job1."sourceTable" = N'PRODTABLE'
and job1."partition" = Receiver."partition"
WHERE
1 = 1
AND Issuer."REFTYPE" IN ( 9, 12 )
AND Receiver."REFTYPE" IN ( 9, 12 )
AND Link."DATAAREAID" = N'company'
INSERT INTO @Results
(
"id"
, "oprNum1"
, "job1Id"
, "job1Type"
, "oprNum2"
, "job2Id"
, "job2Type"
, "minimumDistance"
, "maximumDistance"
, "resourceLocked"
, "durationLocked"
, "slot1"
, "slot2"
, "color"
, "origin"
, "partition"
)
SELECT
"id" = "job1Id" + N'_' + "job2Id"
, "oprNum1"
, "job1Id"
, "job1Type"
, "oprNum2"
, "job2Id"
, "job2Type"
, "minimumDistance"
, "maximumDistance"
, "resourceLocked"
, "durationLocked"
, "slot1"
, "slot2"
, "color"
, "origin"
, "partition"
FROM
@PeggingRelations;
INSERT INTO @Results
(
"id"
, "oprNum1"
, "job1Id"
, "job1Type"
, "oprNum2"
, "job2Id"
, "job2Type"
, "minimumDistance"
, "maximumDistance"
, "resourceLocked"
, "durationLocked"
, "slot1"
, "slot2"
, "color"
, "origin"
, "partition"
)
SELECT
"id" = Job1."id" + N'_' + Job2."id"
, "oprNum1" = Job1."oprNum"
, "job1Id" = Job1."id"
, "job1Type" = Job1."jobType"
, "oprNum2" = Job2."oprNum"
, "job2Id" = Job2."id"
, "job2Type" = Job2."jobType"
, "minimumDistance" = 0
, "maximumDistance" = 2147483647
, "resourceLocked" = CASE Job1."oprNum" WHEN Job2."oprNum" THEN 1 ELSE 0 END
, "durationLocked" = 0
, "slot1" = job1."OVERLAPFACTOR"
, "slot2" = 0.0
, "color" = 0x0000FFFF
, "origin" = N'workorder'
, "partition" = Job1."partition"
FROM
"dbo"."PRODBOM" AS PB
INNER JOIN "dbo"."_company_job" AS Job1
ON Job1."prodId" = PB."INVENTREFID"
and Job1."partition" = PB."partition"
AND Job1."isLast" = 1
AND Job1."sourceTable" = N'PRODTABLE'
AND Job1."jobType" = 4
INNER JOIN "dbo"."_company_job" AS Job2
ON Job2."prodId" = PB."PRODID"
AND Job2."oprNum" = PB."OPRNUM"
AND Job2."isFirst" = 1
and Job2."partition" = PB."partition"
LEFT OUTER JOIN @Results AS Rel
ON Rel."job1Id" = Job1."id"
AND Rel."job2Id" = Job2."id"
AND Rel."slot1" = job1."OVERLAPFACTOR"
AND Rel."slot2" = 0.0
AND Rel."partition" = Job1."partition"
WHERE
1 = 1
AND PB."DATAAREAID" = N'company'
AND PB."INVENTREFTYPE" = 3
AND Rel."Id" IS NULL
AND Rel."partition" = Job1."partition";