我有一个非常简单的存储过程;它第一次运行缓慢,如果输入参数相同,则运行速度很快。第一次运行SQL Server T-SQL查询速度慢,然后快速运行
它返回两个表,表头正在迅速恢复,但第二个表,它作为我与表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
能运行得更快是因为查询和执行计划被缓存的原因。这意味着如果参数不改变,查询会更快,第二次运行时它会更快 – luchosrock
我知道,但是,如何优化查询以及为什么它会变慢?它的正常读数没有任何复杂的计算 –
“第一次运行”是什么意思?就像重新启动SQL Server之后一样?首次运行速度通常会很慢,因为所有数据都必须从磁盘读取到内存中。一旦数据被缓存,在后续运行中会更快,除非在此期间再次强制数据从内存中溢出。如果执行计划被缓存,则不太可能引起显着差异;虽然不是不可能,但编译本身不太可能造成显着的,明显的延迟(除非SQL Server此次生成效率更低的计划)。 –