我有一个非常简单的存储过程;它第一次运行缓慢,然后在相同的输入参数下快速运行。
它返回2个表,第一个表快速返回,但是第二个表,它变得很慢,因为我用表1结果加入它以获得正确的数据
这是我的存储过程代码:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[PR_ReadMdgObj]
(@objId int,
@dtFrom datetime = NULL,
@dtTo datetime = NULL)
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @engine_SensorSource_id INT
SELECT @engine_SensorSource_id = SensorSourceid
FROM dbo.SensorSource
WHERE sourcenameid = 1
AND objectid = @objId
CREATE TABLE #10msgtable
(
rownum int IDENTITY (1, 1) NOT NULL,
MessageId bigint NOT NULL,
ObjectId int NOT NULL,
VectorAngle int NOT NULL,
VectorSpeed int NOT NULL,
Altitude int NOT NULL,
GpsTime datetime NOT NULL,
VisibleSatelites int NULL,
X float, Y float,
engine int,
st int
);
CREATE CLUSTERED INDEX IDX_C_returnTable10_GpsTime
ON #10msgtable (GpsTime);
INSERT INTO #10msgtable
SELECT
[Message].messageid, [Message].objectid,
[Message].vectorangle, [Message].vectorspeed,
[Message].altitude, [Message].gpstime,
[Message].visiblesatelites,
[Message].x, [Message].y,
0 Engine, 0 as t
FROM
dbo.[Message] WITH (nolock)
WHERE
[Message].ObjectId = @objId
AND [Message].GpsTime BETWEEN @dtFrom AND @dtTo
-- AND m.Valid = 1
-- AND m.VectorSpeed < 250
DELETE FROM #10msgtable
WHERE VectorSpeed = 250;
SELECT *
FROM #10msgtable
ORDER BY GpsTime ASC
--- select 2
SELECT
MessageSensors.MessageId,
SensorSource.SourceNameId,
MessageSensors.Value
FROM
dbo.MessageSensors
INNER JOIN
#10msgtable WITH (nolock) ON MessageSensors.MessageId= #10msgtable.MessageId
INNER JOIN
dbo.SensorSource WITH (nolock) ON SensorSource.SensorSourceId = MessageSensors.SensorSourceId
--where MessageSensors.MessageId in (select MessageId from #10msgtable)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
END
这是我的实际执行计划:
https://gist.github.com/aymanstar/3ed882c6330ee6252751ce9dd2f5beac
答案 0 :(得分:0)
您添加的步骤很少。第一次运行总是很慢(因为你已经知道了)。 在你的脚本
with(nolock)
原因由@marc_s delete
。所以修改后的脚本应该是: -
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[PR_ReadMdgObj] (
@objId INT
,@dtFrom DATETIME = NULL
,@dtTo DATETIME = NULL
)
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
--DECLARE @engine_SensorSource_id INT
--SELECT @engine_SensorSource_id = SensorSourceid
--FROM dbo.SensorSource
--WHERE sourcenameid = 1
-- AND objectid = @objId
CREATE TABLE #10msgtable (
rownum INT IDENTITY(1, 1) NOT NULL
,MessageId BIGINT NOT NULL
,ObjectId INT NOT NULL
,VectorAngle INT NOT NULL
,VectorSpeed INT NOT NULL
,Altitude INT NOT NULL
,GpsTime DATETIME NOT NULL
,VisibleSatelites INT NULL
,X FLOAT
,Y FLOAT
,engine INT
,st INT
);
CREATE CLUSTERED INDEX IDX_C_returnTable10_GpsTime ON #10msgtable (
MessageId
,GpsTime
);
INSERT INTO #10msgtable
SELECT [Message].messageid
,[Message].objectid
,[Message].vectorangle
,[Message].vectorspeed
,[Message].altitude
,[Message].gpstime
,[Message].visiblesatelites
,[Message].x
,[Message].y
,0 Engine
,0 AS t
FROM dbo.[Message]
WHERE [Message].ObjectId = @objId
AND [Message].GpsTime BETWEEN @dtFrom
AND @dtTo
AND VectorSpeed <> 250
-- AND m.Valid = 1
-- AND m.VectorSpeed < 250
--DELETE
--FROM #10msgtable
--WHERE VectorSpeed = 250;
SELECT *
FROM #10msgtable
ORDER BY GpsTime ASC
--- select 2
SELECT MessageSensors.MessageId
,SensorSource.SourceNameId
,MessageSensors.Value
FROM dbo.MessageSensors
INNER JOIN #10msgtable ON MessageSensors.MessageId = #10msgtable.MessageId
INNER JOIN dbo.SensorSource ON SensorSource.SensorSourceId = MessageSensors.SensorSourceId
--where MessageSensors.MessageId in (select MessageId from #10msgtable)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
END