Sql Server 2000 Stored Procedure Prevent Parallelism or something? - sql-server

I have a huge disgusting stored procedure that wasn't slow a couple months ago, but now is. I barely know what this thing does and I am in no way interested in rewriting it.
I do know that if I take the body of the stored procedure and then declare/set the values of the parameters and run it in query analyzer that it runs more than 20x faster.
From the internet, I've read that this is probably due to a bad cached query plan. So, I've tried running the sp with "WITH RECOMPILE" after the EXEC and I've also tried putting the "WITH RECOMPLE" inside the sp, but neither of those helped even a little bit.
When I look at the execution plan of the sp vs the query, the biggest difference is that the sp has "Parallelism" operations all over the place and the query doesn't have any. Can this be the cause of the difference in speeds?
Thank you, any ideas would be great... I'm stuck.

If the only difference between the two query plans is parallelism, try putting OPTION (MAXDOP 1) at the end of the query to limit it to a serial plan.
As to why they are different, I'm not sure, but I remember the SQL Server 2000 optimizer as being, um, finicky. Similar to your case, what we usually saw was that ad-hoc query batches would be fast and the same query via sp_executesql would be slow. Never did fully figure out what was going on.
Serial v parallel can definitely explain the difference in speeds, though. On SQL Server 2000, parallel plans use all the processors on the machine, not just the ones it needs:
If SQL Server chooses to use parallelism, it must use all the configured processors (as determined by the MAXDOP query hint configuration) for the execution of a parallel plan. For example, if you use MAXDOP=0 on a 32-way server, SQL Server tries to use all 32 processors even if seven processors might perform the job more efficiently as compared to a serial plan that only uses one processor. Because of this all-or-nothing behavior, if SQL Server chooses the parallel plan and you do not restrict the MAXDOP query hint[...], the time that it takes SQL Server to coordinate all the processors on a high-end server outweighs the advantages of using a parallel plan.
By default, I believe the server-wide setting of MAXDOP is 0, meaning use as many as possible. If you recently upgraded your database server with more processors to help performance, that could ironically explain why your performance is suffering. If that's the case, you might try setting the MAXDOP hint to the number of processors you had before and see if that helps.

try adding SET ARITHABORT ON at the top of the procedure.
as seen here: https://stackoverflow.com/questions/2465887/why-would-set-arithabort-on-dramatically-speed-up-a-query

If you have made many changes to the table and not run a re-index or defragment on the tables in question you probably should. Check out this article. The reason i suggest this is because the procedure at one time was fast and now over time it has degraded performance. I don't think making changes to an already existing procedure that was tested and worked well at one time should change on account of degraded performance over time. This usually only treats the symptoms not the actual problem.

I do know that if I take the body of
the stored procedure and then
declare/set the values of the
parameters and run it in query
analyzer that it runs more than 20x
faster.
Are you sure that it is not the fetching of these params ahead of the SP's execution that's not causing your slowness? With bypassing the population of the params you could be oversimplifying your issue.
Where do these params come from? How are they populated? It seems from your question that you've isolated the stored proc and found out that it might not be the issue.

Could it be a problem with contention? Does this store procedure run at a particular time when other heavy lifting is also happening?

Related

SQL Server CXPACKET timeout

We've got SQL Server 2016 (v13.0.4206.0), by default there is no restrictions for parallelism - any count SQL wants. And it didn't lead any problems... Till now.
For another feature there were written query that unexpectedly raised timeout exception in our application. I was deeply surprised when it was successfully executed with setting up maximum threads per query to 1. Yes, 6 seconds for query is not so good, even accounting to most of time was spent for fetching, but it's far away from 3 minutes timeout!
By the way, executing this query with SQL Server Management Studio works all the time despite of parallelism settings. It seems that something wrong with connection to database, but all other queries works fine, even which much harder then that one.
Our application is built on ASP.NET Core 3.0 (don't know if it matters), database connection is made using System.Data.SqlClient v4.8.0. All I could determine is that there are so much tasks created for this query:
I've tried to watch for execution in sys.dm_os_waiting_tasks (thanks google). I'm not sure I got it right, but it seems that tasks with context_id 0-8 is blocked with those who have context_id 9-16 and vise versa. Obvious example of deadlock, isn't it? But how can SQL Server manage threads to make it without my "help"? Or what am I doing wrong?
Just in case some inappropriate answers:
I won't turn parallelism off (set maximum threads per query to 1) as solution because of some heavy queries in our application;
I don't want to raise Cost Threshold for Parallelism setting because I'm afraid of same problem with another query (guess, a heavier one). So I just want to determine real cause;
Optimizing the query isn't considered (anymore), as according to actual execution plan I can't make it faster - there are enough indexes for it. But I'm ready to rethink after some really weighty arguments.
So, my question is: why does parallelism that I didn't ask for spoil the query execution? And how can I avoid that?
It's true sometimes the engine chooses to use parallel execution (or not to use) which leads to worse performance.
You do not want to control the server option and the cost as you are not sure how this will reflect to other queries, which is understandable.
If you are sure, your query will be execute better without being handle in parallel, you can specify the option just for it using query hints - MAXDOP like this:
SELECT ...
FROM ...
OPTION (MAXDOP 1);
It's easy and you can rollback if needed. Also, you are not affecting other queries.
You are saying that:
Optimizing query isn't considered (anymore), as according to actual execution plan...
The execution plan is sometimes misleading. As a start - you can save your execution plan and open it with SentryOne Plan Explorer - it's free and can give you a better look of what's going on.
Also, if a query is execute for either 3 seconds or 6 minutes, there must be something wrong with it or may be the activity of your database. If it is executed fast in the SSMS always, maybe the engine is using the correct cache plan. I thing it's better to share the query itself and to attach the two plans (serial and parallel) and spend more time tuning it.

SQL Server 2000 caching

I have one question in order to speed up SQL Server 2000.
I want to use caching mechanism, but I don't know how to use.
I found some articles about it, but can you give an example for how to use.
For example:
there is a stored procedure - sp_stackOverFlow - it executes when every user enter to the program/web site and it is clear it makes slower running.
Is there a way of caching sp_stackOverFlow in every 2 minutes or another?
Your question isn't clear, not least because it isn't obvious what the stored procedure does. If the results are different for every execution and/or user then they cannot easily be cached anyway.
But more fundamentally, "I have a slow stored procedure" does not automatically mean "I need caching"; the database engine itself already caches data when it can. You need to understand why the stored procedure is running slowly: underpowered hardware, poor TSQL code, poor data model design and poor indexing are all very common issues that have major effects on performance.
You can find a lot of information on this site and by Googling about how to troubleshoot slow execution times for procedures, but you can start by reviewing the execution plan for the procedure in Query Analyzer and tracing the execution using Profiler. That will immediately tell you which statements are taking the most time, if there are table scans happening etc.
Because performance troubleshooting is potentially complex, if you need more assistance please post short, specific questions about individual issues. If the code for your stored procedure is very short (< 30 lines formatted) people may be willing to comment on it directly, otherwise it would be better to post only the individual SQL statements that are causing a problem.
Finally, mainstream support for MSSQL 2000 stopped 3 years ago, so you should definitely look into upgrading to newer version. The performance tools in newer versions will make resolving your issue much easier.

What are these sys.sp_* Stored Procedures doing?

I'm tracking down an odd and massive performance problem in my SQL server installation. On my system, a particular stored procedure takes 2 minutes to execute; on a colleague's system it takes less than 1 second. We have similar databases/data and configurations, but there's obviously something very different.
I ran the SP in question through the Profiler on both systems and noticed something odd. On My system, I see 9 entries with the following properties:
The Duration is way high relative to other rows. I have values as high as 37,698 and as low as 1734. On the "fast" system the maximum duration (for the entire SP call) is 259.
They are executed for two databases related to the one that contains the SP I'm running. (This SP makes calls via Linked Servers to these two databases).
They are executions of one of the following system SPs:
sp_tables_info_90_rowset
sp_check_constbytable_rowset
sp_columns_90_rowset
sp_table_statistics2_rowset
sp_indexes_90_rowset
I can't find any Googleable documentation on what these are, why they would be so slow, or why they would run on one system but not the other. Does anyone know what they're all about?
Try manually updating statistics on that table.
UPDATE STATISTICS [TableName]
Then double check that the database option to AutoUpdateStatistics is TRUE. Even if it is, though, I've seen cases where adding large amounts of data to a table doesn't always cause the statistics to update in a timely way, and queries can be slow.
I don't know the answer to your question. But to try to fix the problem you're having (which, I assume, is what you're actually interested in), the first thing I'd do is run a re-index on the tables you're querying. This frequently will fix any kind of slowness when the conditions are as you described (same database structure, different data/database, same query).
These are the tables created when you have linked server calls. These are called work tables created in Tempdb. They are automatically created by the database engine for temporary operations like Spooling etc.
Those sp's mean your query is hitting linked servers by using synonyms. This should be avoided whenever possible.
I'm not familiar with those specific procedures, but you can try running:
SELECT object_definition(object_id('Procedure Name'))
To get a better idea of what's going on under the hood.
Last index rebuild? Last statistics update?
Otherwise, these stored procs are used by the SQL Server client too... no? And probably won't cause these errors

Cross DB stored procedures performance in SQL Server 2008

Let's have:
$DB an SQL Server database
$DBSP1 an SQL Server database containing stored procedures referencing $DB
$DBSP2 is exactly like $DBSP1
$SP is a stored procedure
Running $SP on $DBSP1 from C# code takes around 1.5s.
Running $SP on $DBSP2 from C# code takes around 0.5s.
The C# code is very simple and use SqlClient with default parameters.
When I execute $SP in an SQL console on both $DBSP1 and $DBSP2, it takes 0.4s.
The only difference between the two code databases is $DBSP1 is in production and is a bit loaded, while $DBSP2 is idle. There is no data in code databases, only stored procedures and views over $DB.
Can someone suggest reasons why this happen? Since all the work happens in $DB which is equally loaded in both cases I would expect performances to be similar.
The difference in speed came from different query plans. $SP is a complicated stored procedure and its initial query plan may vary vastly depending on the first query hitting it. And at this point we were not controlling the first request since right after deploying the $SP, it was published in production.
We tried providing hints about $SP parameters both at $SP levels and query levels, without success. So instead, we warm up the $SP before deploying with well crafted queries known to generate the correct query plan.
I think you have your answer. $DBSP1 is busy. It still has to task switch and prioritize work that comes in even though most of the work is happening in $DB.
Further, depending on the amount of data being transferred, the network activity comes into play. If $DBSP1 is sending / receiving a fair amount of data, that lessens the amount of available bandwidth for it to communicate with $DB and will cause result sets to transfer slower.
1) Check that both servers have the same indexes defined on each table
2) Rebuild Indexes (or at a minimum, update Statistics)
Do you have regular index maintenance jobs scheduled? Sounds like out of date statistics or fragmented indexes are causing the discrepancy..
Suggest you run profiler to see what is happening, but often the workload on a production database makes everything run slower. Also statistics may be out of date. Performance is rarely the same between two servers in my experience.
Measure.
Add SET STATISTICS TIME ON and SET STATISTICS IO ON to your C# and on the sql console call as well. In C#, hook up the SqlConneciton.InfoMessage event to capture the informational messages and display them. also separate the time measured for the SqlConnection.Open() call and the SqlCommand.ExecuteNonQuery call.
Then you'll be able to tell the difference.
different conenction Open() times?
different compilation/execution times ?
different logical reads/physical reads ratio?
different logical reads count?

Why is query slow but procedure fast on SQL Server?

Why is it that if I run my query as a parameterized procedure it runs 10 times faster then if I run it directly as a parameterized query?
I'm using the exact same query in both cases, and it doesn't matter if I'm calling from Management Studio or an SqlCommand from code.
EDIT: The execution plan looks different. So, why? I'm calling it with EXACTLY the same set of parameters.
EDIT: After more testing it seems the 10x slowdown only occurs when running the parameterized query from SQL Management Studio.
One thing I've seen recently is that if you set up the query parameters wrong it can cause major problems.
For example, say you have a parameter for an indexed varchar column and set it up from .Net using the SqlCommand's AddWithValue() method. You're in for a world of hurt with this scenario. .Net uses unicode strings and will set up your parameter as an nvarchar rather than varchar. Now sql server won't be able to use your index, and you'll see a significant performance penalty.
Find out if they are using the same execution plan is to display it when running. Use "include actual execution plan" in management studio and see what is the difference.
The connection-level settings can be critical in some cases, especially ANSI NULLS, CONCAT NULL YIELDS NULL, etc. In particular, if you have calculated persisted indexed columns (including promoted "xml" columns), then it won't trust the pre-calculated, index value if the settings aren't compatible, and will recalculate for each row (i.e. table scan instead of index seek).
Parameterized queries have a lot of advantages, including often a hefty performance increases.
Caching of queries
String Concatenation problems minimized
addressing SQL injection
Data does not have to be converted to a string before processing
Parameter sniffing may be affecting the stored procedure performance.
http://omnibuzz-sql.blogspot.com/2006/11/parameter-sniffing-stored-procedures.html
Stored procedures can run faster because the execution plan is cached by sql server.
But 10 times performance is suspicious.
Does it run the same the First time after you've cleared the stored execution plans? You can use these commands to clear the cache. But they clear the whole servers cache so do it only on development servers.
DBCC FREEPROCCACHE
DBCC FLUSHPROCINDB (<dbid>)
Are you running these directly on the SQL server to eliminate any network I/O from the performance testing?
My guess is that it is running slowly the first time, then once it is cached it is running faster.

Resources