July 9, 2007 at 2:09 pm
Hi all,
We have 2 databases on the same server. One is production, the other is for development. They have identical tables, stored procedures and functions. There are slight differences in the amount of data in each, but nothing drastic.
There was this one stored procedure that was running slowly on production, but really fast on test. The sp was not very complex, just a select and a function call:
ALTER procedure [dbo].[getTablePrefs]
@resourceHash uniqueIdentifier
as
select enabled, ',' as c
from reqTablePref
where person_id = [dbo].[getRegisIDFromHash](@resourceHash)
ORDER BY columnNum
FOR XML AUTO, ELEMENTS
The slow down appeared to be the function call. If we substituted that with a subquery, it ran almost instantly. With the function, up to 19 seconds. When I tested the function independently it ran instantly. And like I said, in the test database on the same server the sp ran instantly with no problems.
There was only one difference between the two dbs. The table reqTablePref didn't have a primary key set in production. I fixed that, but it made no difference to the execution of the sp.
Right now we have changed the sp in our production db to use a sub-query. Anyone got any ideas on what we are missing?
Thanks!
John
July 9, 2007 at 3:53 pm
Update statistics reqTablePref WITH FULLSCAN,ALL.
Then recompile your stored procedure
Good luck!
* Noel
July 9, 2007 at 4:31 pm
No joy
Still takes 16-18 seconds to execute.
3 of us have looked at this db just to make sure we haven't missed anything. It makes no sense that the function will run instantly on it's own, that the stored procedure will run instantly using a sub-query, but will take so long when put together.
Thanks again for any ideas,
John
fyi, here is the sp with the sub-query:
ALTER procedure [dbo].[getTablePrefs]
@resourceHash uniqueIdentifier
as
select enabled, ',' as c
from reqTablePref
--where person_id = [dbo].[getRegisIDFromHash](@resourceHash)
where person_id =
(
select person_id from person where hash = @resourceHash
)
ORDER BY columnNum
FOR XML AUTO, ELEMENTS
July 10, 2007 at 1:38 am
Firstly, get rid of the nested select. Functions and nested selects are inherently slow.
Rather use another way such as a join, case statement etc to suite.
This however does not explain your problem.
What are the two query plans? Identical? How about the plan of the function?
A function may run instantly when used in isolation but with a function or nested select as you have there, it is executed for every row returned from that portion of the select. So, if your first DB is doing an index seek, it will be quicker than the second doing an index scan..
Also, you mention a difference in rows. How large is the difference?
Cheers,CrispinI can't die, there are too many people who still have to meet me!It's not a bug, SQL just misunderstood me!
July 10, 2007 at 3:09 am
Thats the issue with inline function. SQL will not be able to make estimates and assume 1 row which can make plan bad. How many rows are there in person table? My guess is - "many rows"
July 10, 2007 at 6:37 am
Are you getting the same query plan on both servers?
July 10, 2007 at 9:54 am
Didn't know functions were slow, thanks for the info!
As for differences in rows between test and production: The Person tables both have the same (128000), and the reqTablePref tables are 450 in production, 31 in test.
Is the query plan the same as the execution plan? I have never had to delve this far into SQL server before, so some things are new to me (Yet I am the closest thing we have to a dba.. Scary, huh?). I checked the actual execution plans if that's what you mean.
The execution plans on both production and test for the sp and the function are identical.
(an aside question: Does anyone know why trying to display an actual execution plan in SQL Server Management studio causes it to crash? I used enterprise manager to get these plans)
Thanks for the help!
John
EDIT: Both the production and test databases are on the same server.
July 10, 2007 at 10:07 am
Functions used in a select will slow a query down as the contents of the function is run for each and every row. but I said that already
Weird though that the DB's are on the same server and not performing the same.
You updated stats in the DB?
What are the execution plans? Any table or index scans?
Try removing the function and changing the query slightly.
Other than that, I'm rather lost...
As to your other question, remove the FOR XML when showing the plan. it's an annoying bug. Cannot show plan with XML results...
Cheers,CrispinI can't die, there are too many people who still have to meet me!It's not a bug, SQL just misunderstood me!
July 10, 2007 at 10:57 am
I updated stats on person and reqTablePref, recompiled the sp and function.
On the execution plans, they start with a clustered index scan on reqTablePref which is 78% (77% on test), then a filter 0%, sort 22% (23% on test), then a select 0%.
With the function removed and a sub query put in instead, it runs as fast as the original sp on test. When the function is put back in, it slows to a crawl. Changed the fields to be queried, no change. Deleted and recreated the sp. No change.
It's totally mystifying.
There is one thing I did notice.. I was looking at all the options on the execution plans, and when I did "Manage Statistics" I noticed that on the production db plan, there were 4 columns for reqTablePref, but on the test db plan there were only 2. Would that make a difference?
Thanks for the all the help though (and the show plan fix!).
John
Viewing 9 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic. Login to reply