我有一个在应用程序中运行的存储过程。它通常在500毫秒内完成,但有时可能需要5秒。如何消除5秒运行?非常感谢任何帮助。
--Table definition:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID (N'[dbo].[EventValue]') AND type in (N'U'))
DROP TABLE [dbo].[EventValue]
GO
CREATE TABLE [dbo].[EventValue](
[MetricId] [int] NOT NULL,
[AttributeId] [int] NOT NULL,
[DataRunId] [int] NOT NULL,
[CurrentDataTime] [bigint] NOT NULL,
[AType] [bit] NOT NULL,
[Mm] [int] NOT NULL,
[ReceivedDataTime] [bigint] NOT NULL,
[ValueList] nvarchar(4000) NULL,
[MState] [int] NULL,
[OId] [int] NULL,
[EventStartTime] [bigint] NULL,
[EventEndTime] [bigint] NULL,
[EventEST] [bigint] NOT NULL,
[EventEE] [int] NULL
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_EventValue_DataRunId_EventEndTime] ON [dbo].[EventValue]
(
[DataRunId] ASC,
[EventEndTime] ASC
)
INCLUDE ( [CurrentDataTime]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE CLUSTERED INDEX [IX_EventValue_DataRunId_CurrentDataTime ] ON [dbo].[EventValue]
(
[DataRunId] ASC,
[CurrentDataTime] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_EventValueEventEST] ON [dbo].[EventValue]
(
[EventEST] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DataRun]') AND type in (N'U'))
DROP TABLE [dbo].[DataRun]
GO
CREATE TABLE [dbo].[DataRun](
[Id] [int] IDENTITY(1,1) NOT NULL,
[PersonId] [uniqueidentifier] NOT NULL,
[WallTime] datetime2(7) NOT NULL,
[DataTimeSeed] [bigint] NOT NULL,
CONSTRAINT [PK_TimeMapping] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)ON [PRIMARY] GO
--Stored procedure:
CREATE PROC [dbo].[Event_Get]
@PersonId UNIQUEIDENTIFIER,
@startTime relativeTime,
@duration BigInt , -- in milliSeconds
@storageBlock int -- in milliSeconds
AS
BEGIN
DECLARE @EventValueResultSet TABLE
(
[MetricId] [int] NOT NULL,
[AttributeId] [int] NOT NULL,
[CurrentDataTime] [bigint] NOT NULL,
[AType] [bit] NOT NULL,
[Mm] [int] NOT NULL,
[ReceivedDataTime] [bigint] NOT NULL,
[CompressedValueList] varbinary(8000) NULL,
[ValueList] nvarchar(4000) NULL,
[MState] [int] NULL,
[OId] [int] NULL,
[EventStartTime] [bigint] NULL,
[EventEndTime] [bigint] NULL,
[EventEE] [int] NULL,
[DataRunSeed] [bigint] NOT NULL,
[DataRunWallTime] datetime2(7) NOT NULL
)
DECLARE @endTime bigint = @startTime + @duration;
DECLARE @blockStartTime bigint = 0;
With C2(CurrentDataTime ) AS
(
SELECT MIN(CurrentDataTime )
FROM dbo.EventValue WV WITH (NOLOCK)
INNER JOIN dbo.DataRun_ DR WITH (NOLOCK)
ON WV.DataRunId = DR.Id AND DR.PersonId = @PersonId
WHERE CurrentDataTime > (@startTime - @storageBlock)
AND CurrentDataTime < @startTime
)
SELECT @blockStartTime = ISNULL(CurrentDataTime , @startTime) FROM C2;
-- Events between @startTime and @endTime
INSERT INTO @EventValueResultSet
(MetricId, AttributeId, CurrentDataTime, AType,
Mm, ReceivedPhysioDataTime, ValueList,
MState, OId, EventStartTime, EventEndTime, EventEE,
DataRunSeed, DataRunWallTime)
SELECT MetricId, AttributeId, CurrentDataTime , AType,
Mm, ReceivedPhysioDataTime, ValueList,
MState, OId, EventStartTime, EventEndTime, EventEE,
DR.DataTimeSeed, DR.WallTime
FROM dbo.EventValue EV WITH (NOLOCK)
INNER JOIN dbo.DataRun_ DR WITH (NOLOCK)
ON EV.dataRunId = DR.Id
AND DR.PersonId = @PersonId
WHERE PhysioCurrentDataTime BETWEEN @blockStartTime AND @endTime
-- Events started before @startTime and active in duration, including
-- (1) events that started before @startTime and have not ended (endTime = 0)
-- (2) events that started before @startTime and ended after @startTime
INSERT INTO @EventValueResultSet
(MetricId, AttributeId, CurrentDataTime , AType,
Mm, ReceivedPhysioDataTime, ValueList,
MState, OId, EventStartTime, EventEndTime, EventEE,
DataRunSeed, DataRunWallTime)
SELECT MetricId, AttributeId, CurrentDataTime , AType,
Mm, ReceivedDataTime, ValueList,
MState, OId, EventStartTime, EventEndTime, EventEE,
DR.DataTimeSeed, DR.WallTime
FROM dbo.EventValue EV WITH
(NOLOCK,INDEX(IX_EventValueDataRunId_EventEndTime))
INNER JOIN dbo.DataRun_ DR WITH (NOLOCK)
ON EV.dataRunId = DR.Id
AND DR.PersonId = @PersonId
WHERE (CurrentDataTime < @blockStartTime )
AND (EventEndTime = 0 OR EventEndTime >= @blockStartTime )
--
-- Other Statements using @EventValueResultSet
--
SELECT * FROM @EventValueResultSet ORDER BY MetricId, CurrentDataTime
END
答案 0 :(得分:0)
将两个插件合并为单个插件,如下所示
INSERT INTO @EventValueResultSet(....)
SELECT ....
....
FROM dbo.EventValue EV WITH (NOLOCK))
INNER JOIN dbo.DataRun_ DR WITH (NOLOCK)
ON EV.dataRunId = DR.Id
AND DR.PersonId = @PersonId
WHERE PhysioCurrentDataTime BETWEEN @blockStartTime AND @endTime
OR ( ( CurrentDataTime < @blockStartTime )
AND ( EventEndTime = 0
OR EventEndTime >= @blockStartTime ) )