Stored Procedure; Insert Slowness
-
02-07-2019 - |
Question
I have an SP that takes 10 seconds to run about 10 times (about a second every time it is ran). The platform is asp .net, and the server is SQL Server 2005. I have indexed the table (not on the PK also), and that is not the issue. Some caveats:
- usp_SaveKeyword is not the issue. I commented out that entire SP and it made not difference.
- I set @SearchID to 1 and the time was significantly reduced, only taking about 15ms on average for the transaction.
- I commented out the entire stored procedure except the insert into tblSearches and strangely it took more time to execute.
Any ideas of what could be going on?
set ANSI_NULLS ON
go
ALTER PROCEDURE [dbo].[usp_NewSearch]
@Keyword VARCHAR(50),
@SessionID UNIQUEIDENTIFIER,
@time SMALLDATETIME = NULL,
@CityID INT = NULL
AS
BEGIN
SET NOCOUNT ON;
IF @time IS NULL SET @time = GETDATE();
DECLARE @KeywordID INT;
EXEC @KeywordID = usp_SaveKeyword @Keyword;
PRINT 'KeywordID : '
PRINT @KeywordID
DECLARE @SearchID BIGINT;
SELECT TOP 1 @SearchID = SearchID
FROM tblSearches
WHERE SessionID = @SessionID
AND KeywordID = @KeywordID;
IF @SearchID IS NULL BEGIN
INSERT INTO tblSearches
(KeywordID, [time], SessionID, CityID)
VALUES
(@KeywordID, @time, @SessionID, @CityID)
SELECT Scope_Identity();
END
ELSE BEGIN
SELECT @SearchID
END
END
Solution
Why are you using top 1 @SearchID
instead of max (SearchID)
or where exists
in this query? top
requires you to run the query and retrieve the first row from the result set. If the result set is large this could consume quite a lot of resources before you get out the final result set.
SELECT TOP 1 @SearchID = SearchID
FROM tblSearches
WHERE SessionID = @SessionID
AND KeywordID = @KeywordID;
I don't see any obvious reason for this - either of aforementioned constructs should get you something semantically equivalent to this with a very cheap index lookup. Unless I'm missing something you should be able to do something like
select @SearchID = isnull (max (SearchID), -1)
from tblSearches
where SessionID = @SessionID
and KeywordID = @KeywordID
This ought to be fairly efficient and (unless I'm missing something) semantically equivalent.
OTHER TIPS
Enable "Display Estimated Execution Plan" in SQL Management Studio - where does the execution plan show you spending the time? It'll guide you on the heuristics being used to optimize the query (or not in this case). Generally the "fatter" lines are the ones to focus on - they're ones generating large amounts of I/O.
Unfortunately even if you tell us the table schema, only you will be able to see actually how SQL chose to optimize the query. One last thing - have you got a clustered index on tblSearches?
Triggers!
They are insidious indeed.
- What is the clustered index on tblSearches? If the clustered index is not on primary key, the database may be spending a lot of time reordering.
- How many other indexes do you have?
- Do you have any triggers?
- Where does the execution plan indicate the time is being spent?