我有一個非常簡單的存儲過程;它第一次運行緩慢,如果輸入參數相同,則運行速度很快。第一次運行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此次生成效率更低的計劃)。 –