Re: Update statement performance decreases in stored proc
From: Jacco Schalkwijk (jacco.please.reply_at_to.newsgroups.mvps.org.invalid)
Date: 01/12/05
- Next message: Rafa®: "T-SQL Debugger"
- Previous message: a: "sp and DNS"
- In reply to: Hugo Kornelis: "Update statement performance decreases in stored proc"
- Next in thread: Hugo Kornelis: "Re: Update statement performance decreases in stored proc"
- Reply: Hugo Kornelis: "Re: Update statement performance decreases in stored proc"
- Reply: Hugo Kornelis: "Re: Update statement performance decreases in stored proc"
- Messages sorted by: [ date ] [ thread ]
Date: Wed, 12 Jan 2005 12:48:57 -0000
Hugo,
Have you had a look at the execution plan of the stored procedure? It might
be that it is not using the index you create, because it is created after
all the inserts happen on the table. Creating an index on a table will not
automatically mark stored procedures that use that table for recompilation.
You can try if moving the create index statement to a place before the
inserts will make a difference in procedure execution time.
-- Jacco Schalkwijk SQL Server MVP "Hugo Kornelis" <hugo@pe_NO_rFact.in_SPAM_fo> wrote in message news:gi4au0de3d9fff1u440bdjc7anij9112cu@4ax.com... > Hi all, > > I'm having some trouble finding out why an update statement that runs in > less than 2 seconds from Query Analyzer takes no less than 24 minutes when > in a stored procedure. Here are the important parts of the stored proc: > > CREATE PROC MyProc > AS > -- Create temp table, fill it with starting data > CREATE TABLE #GenRglTekst > (sorteercode varchar(400) NOT NULL > PRIMARY KEY, > GenRglTekst varchar(1000) NOT NULL, > -- some other columns snipped rfom this usenet post > ) > INSERT #GenRglTekst > (sorteercode, GenRglTekst, > -- some other columns snipped from this usenet post > ) > SELECT a.sorteercode, a.n_GenRglSjab, > -- some other columns snipped from this usenet post > FROM XXX AS a -- Table names have been changed > INNER JOIN YYY AS b -- to protect the innocent > ON -- Join condition snipped > -- Create supporting index. > CREATE INDEX #GenRglTekst_index ON #GenRglTekst > (GenRglObject_objectsoortnaam, GenRglObject_objectnaam) > > -- Snipped a lot of queries that change the value of GenRglTekst, > -- using the other columns, plus data from lots of other tables. > -- I have no problem with those queries. > > -- After all changes to GenRglTekst have been made, I run this query: > UPDATE dbo.GenRegel > SET GenRglTekst = > (SELECT GenRglTekst > FROM #GenRglTekst AS # > WHERE #.sorteercode = GenRegel.sorteercode) > WHERE EXISTS > (SELECT * > FROM #GenRglTekst AS # > WHERE #.sorteercode = GenRegel.sorteercode) > -- Clean up temp table > DROP TABLE #GenRglTekst > -- End stored proc > GO > > The last change I made to this stored procedure is the definition of the > indexes. In the previous version, the primary key was nonclustered and the > supporting index was clustered, but testing from QA showed that clustering > the PK gave a slight performance gain. However, when I incorporated these > changes in the stored proc, my performance suddenly plummeted. Using > Profiler, I found that this was casued by the UPDATE statement at the end > of the stored proc. But I also found that if I copy the entire contents of > the stored proc to QA and run it from there, the same UPDATE statement > runs in only 2 seconds!! > > You'll find the DDL for dbo.GenRegel and the execution plans for the > queries from stored proc and from QA below, but first my questions: > > 1. What can be the cause of the huge performance difference between > running from QA and running from stored proc? It can't be parameter > sniffing, as there is no parameter involved. It also can't be the use of a > cached plan, as I also ran tests with the WITH RECOMPILE option on the > stored proc AND I ran a test after executing DBCC FREEPROCCACHE. > > 2. Is there any way to make sure that on compilation of the proc, the > optimizer chooses the better plan (the one already chosen when running > from QA)? > (Note - changing the UPDATE statement to proprietary UPDATE FROM is not an > option. GenRegel is a view with an INSTEAD OF trigger and these are not > allowed in an UPDATE FROM statement). > > The DDL for the view GenRegel and the underlying base tables (snipping all > irrelevant columns): > > -- Table below has 97514 rows in my test > CREATE TABLE dbo.f_GenRegel (sorteercode varchar(400) NOT NULL, > GenRglTekst varchar(1000) NULL, > g_DoopAanw char(1) NOT NULL, > g_ConvNr int NULL, > g_Versie char(1) NOT NULL, > -- snip other columns > CONSTRAINT k_f_GenRegel PRIMARY KEY CLUSTERED(sorteercode, > g_Versie)) > GO > -- Table below has 1 row in my test > CREATE TABLE dbo.g_f_Conv > (g_ConvNr int NOT NULL > ,g_Actief varbinary(85) NULL > -- snip other columns > ,CONSTRAINT g_k_f_Conv PRIMARY KEY > NONCLUSTERED(g_ConvNr)) > GO > CREATE CLUSTERED INDEX g_x_Conv ON dbo.g_f_Conv(g_Actief) > GO > > -- The view below has 48757 rows in my test (half the rows in f_GenRegel) > -- 41241 of these rows have a matching row in #GenRglTekst > CREATE VIEW dbo.GenRegel > AS > SELECT f.sorteercode, > f.GenRglTekst, > -- snip other columns > FROM dbo.f_GenRegel AS f > LEFT JOIN dbo.g_f_Conv AS c > ON c.g_Actief = SUSER_SID() > WHERE f.g_DoopAanw = 'j' > AND f.g_Versie = CASE WHEN f.g_ConvNr = c.g_ConvNr THEN 'n' > ELSE 'o' END > > > > Best, Hugo > -- > > (Remove _NO_ and _SPAM_ to get my e-mail address)
- Next message: Rafa®: "T-SQL Debugger"
- Previous message: a: "sp and DNS"
- In reply to: Hugo Kornelis: "Update statement performance decreases in stored proc"
- Next in thread: Hugo Kornelis: "Re: Update statement performance decreases in stored proc"
- Reply: Hugo Kornelis: "Re: Update statement performance decreases in stored proc"
- Reply: Hugo Kornelis: "Re: Update statement performance decreases in stored proc"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|