我有一个UDF
,提供了大量数据。使用了几个表变量。目前,没有创建索引。
使用testdata的运行时大约 30秒。
仅将表变量更改为临时表(UDF
之外,因为不允许#tables
),会显着降低运行时间。这是 3秒。
这个article解释了这些差异,但我没有看到这一点,它负责这种性能 - 增量。
无论如何 - 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";