I have a stored procedure that accepts three parameters and uses cursors to gather data. The strange thing is the amount of time that it takes to run the SP. At times it will take 5-10 minutes to run and return back only 300 rows. By running the individual queries within the cursors the data seems to return very quickly. I'm a little stumped as to why running it as a whole takes so long. If anyone can point out any mistakes or fixes I may need to may to my query it would be greatly appreciated.
USE [AW]
GO
/****** Object: StoredProcedure [dbo].[Issue_Report] Script Date: 07/25/2012 15:06:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Issue_Report]
@MinDate DateTime,
@MaxDate DateTime,
@PSNumParam varchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Setup Temp Table
DECLARE @TempIssueData TABLE
(
[Date] datetime,
[SerialNum] varchar(MAX),
[LotNum] varchar(MAX),
[CatalogNum] varchar(MAX),
[PSNum] varchar(MAX),
[Description] varchar(MAX),
[ORCaseNum] varchar(MAX),
[UserName] varchar(MAX),
[Issued_From] varchar(MAX),
[Issued_To] varchar(MAX),
[Surgical_Specalty] varchar(MAX),
[surgeon] varchar(50),
[SurgeryEndDate] datetime
)
-- Declare Variables (easier for debugging)
DECLARE @StartDate datetime = @MinDate
DECLARE @EndDate datetime = @MaxDate
DECLARE @Date datetime
DECLARE @SurgeryEndDate datetime
DECLARE @SerialNum varchar(MAX)
DECLARE @LotNum varchar(MAX)
DECLARE @CatalogNum varchar(MAX)
DECLARE @PSNum varchar(MAX)
DECLARE @Description varchar(MAX)
DECLARE @ORCaseNum varchar(MAX)
DECLARE @UserName varchar(MAX)
DECLARE @Issued_From varchar(MAX)
DECLARE @Issued_To varchar(MAX)
DECLARE @Surgical_Specialty varchar(MAX)
DECLARE @Surgeon varchar(50)
DECLARE @ItemID uniqueidentifier
DECLARE @LocationID uniqueidentifier
DECLARE @UserID uniqueidentifier
DECLARE @UnitLocation uniqueidentifier
-- Fix EndDateTime to include the whole day
IF(SELECT CONVERT(varchar,@MaxDate, 108) AS TimeOnly) = '00:00:00'
BEGIN
SET @EndDate = DATEADD(SECOND, 86400,@MaxDate)
END
-- Setup Parameters
IF (@PSNumParam ='') BEGIN SET @PSNumParam = NULL END
-- Setup Cursor
DECLARE curs_GetIssueData CURSOR FOR
SELECT item.ID, item.SerialNumber, item.LotNumber, items.PartNumber, items.CrossRefID, items.Description, item.LocationID
FROM dbo.item WITH (INDEX(Stat_LastUpdated)) INNER JOIN dbo.items ON item.ItemID = items.ID
WHERE (dbo.item.Stat = 3) AND (dbo.item.LastUpdated BETWEEN @StartDate AND @EndDate) AND Tracking='1'
AND CrossRefID = ISNULL(@PSNumParam, CrossRefID)
OPEN curs_GetIssueData
-- Start Reading
FETCH NEXT FROM curs_GetIssueData INTO @ItemID, @SerialNum, @LotNum, @CatalogNum, @PSNum, @Description, @LocationID
WHILE (@@FETCH_STATUS = 0)
-- BEGIN WHILE
BEGIN
SET @Issued_From = NULL
BEGIN
SELECT @Issued_From = ISNULL(Locations.Name, 'N/A')
FROM dbo.Locations
WHERE Locations.ID = @LocationID
END
BEGIN
-- Setup Cursor
DECLARE curs_GetTransData CURSOR FOR
SELECT TOP 1 ORCaseNumber, SurgicalSpecialty, UserID, ORNumber, TransDate, Surgeon, EndDateTime
FROM dbo.transactions
WHERE transactions.ItemID = @ItemID AND transactions.TransactionTypeID in (8,9,10) AND transactions.TransDate BETWEEN @StartDate and @EndDate
ORDER BY transactions.TransDate desc
OPEN curs_GetTransData
-- Start Reading
FETCH NEXT FROM curs_GetTransData INTO @ORCaseNum, @Surgical_Specialty, @UserID, @Issued_To, @Date, @Surgeon, @SurgeryEndDate
WHILE (@@FETCH_STATUS = 0)
-- BEGIN GetTransData WHILE
BEGIN
-- Reset UserName
SET @UserName = NULL
SET @UnitLocation = NULL
BEGIN
SELECT @UnitLocation = Unit.LocationID
FROM dbo.Unit
WHERE UnitType='4' and Unit.LocationID = @LocationID
END
-- Check to see if UserID is NULL
IF @UserID IS NULL AND @UnitLocation IS NOT NULL
BEGIN
SET @UserName = 'CORONA'
END
ELSE
BEGIN
SELECT @UserName = dbo.users.LastName + ', ' + dbo.users.FirstName
FROM dbo.users
WHERE users.ID = @UserID
END
FETCH NEXT FROM curs_GetTransData INTO @ORCaseNum, @Surgical_Specialty, @UserID, @Issued_To, @Date, @Surgeon, @SurgeryEndDate
-- END GetTransData WHILE
END
-- CLEANUP
CLOSE curs_GetTransData
DEALLOCATE curs_GetTransData
END
BEGIN
INSERT INTO @TempIssueData
VALUES(
@Date,
@SerialNum,
@LotNum,
@CatalogNum,
@PSNum,
@Description,
@ORCaseNum,
@UserName,
@Issued_From,
@Issued_To,
@Surgical_Specialty,
@Surgeon,
@SurgeryEndDate
)
END
-- Fetch next record
FETCH NEXT FROM curs_GetIssueData INTO @ItemID, @SerialNum, @LotNum, @CatalogNum, @PSNum, @Description, @LocationID
-- END WHILE
END
-- CLEANUP
CLOSE curs_GetIssueData
DEALLOCATE curs_GetIssueData
SELECT * FROM @TempIssueData ORDER BY [Date] Desc, [Issued_From]
END
Obviously, You create a temptable you need 4 times more minimal for temp table
1. Select Query Execution time
2. Insert Query Execution time in Cursor
3. Insert Query Execution time in TempTeble+Cursor runtime
4. Select Temeptable Execution time same as 1
Try to remove cursor and select your query with joins not with cursors it may be possible to generate such sql select query
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.