I have a stored procedure that takes 1 parameter. When I run the stored procedure from SQL Server Management Studio, it runs in 2-4 seconds. When I call it with a console application, it takes 30+ seconds. The SQL Server is remote and both SSMS and my application are being run from my local machine so I don't think it's a networking issue.
I've ran the SQL Server Profiler to try to track down the issue and one thing I'm seeing is that when it's run from SSMS it starts the statement, recompiles it, then starts it over again, then completes it, like this:
SP:StmtStarting
SP:Recompile
SQL:StmtRecompile
SP:StmtStarting
SP:StmtCompleted
The 2 recompile entries have an EventSubClass of "2 - Statistics changed"
From the app I only see entries for SP:StmtStarting & SP:StmtCompleted, no recompile entries.
I'm calling exactly the same stored procedure with the same parameter value. Why does SSMS recompile based on statistics but my console app does not?
After researching and troubleshooting it appears to be entirely due to SET_ARITHABORT_ON. SSMS defaults this to 'ON' while the .net sql client defaults it to 'OFF' so it was going with 2 different execution plans, although I'm not entirely sure why the two plans are so drastically different.
I overrode the OpenConnection() method to open the connection set it to ON and my application then had the same performance as SSMS. I hope this helps anyone else who stumbles upon this.
Related
I have an issue with performing sql queries, that I dont know what to do about. Tried many things and many creative Google searches.
I have a website that connects (ADO.NET) to a SQL Server 14 (we switched from version 10 where everything worked). From the website a search is performed and when the search result only returns one row, then everything works fine. When the search result returns more than a single row, then I get a timeout from SQL server.
Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the
server is not responding.
The SQL query is excatly the same. Only the parameter changes.
All SQL queries works fine within SQL Management studio.
The SQL Query uses a few views and joins and is very simple with just one parameter. Within management studio it takes 2-3 seconds to complete.
If I change back to the identical database on the old SQL Server 10, then it works again.
What I have tried:
1. Checked the execution plan and its identical for both searches.
2. Changed server memory allocation.
3. sp_refresview.
4. SQL Profiler gives no warnings or raised eyebrows.
5. sp_who2 shows no blocking.
6. Changed Remote Query Timeout to 0 (no timeout).
7. Increased timeout in web.config to 120 seconds.
8. set arithabort = on.
9. set nocount = on.
Still get the timeout.
I'm so confused...
EDIT
As far as I can see, the SQL Profiler tells me that the SQL transactions completes without any problems. But for some reason the result never reaches the web server. It only happens for specific SQL Queries so for the most part everything is fine with the communication to/from the SQL Server and the web server.
Also when I run the website locally from Visual Studio, then everything works perfectly! No timeouts or anything. I only happens for SQL Query XYZ from the web server.
Scenario: System in a VM in Azure using MVC and a SQL Database (not in the VM) working under normal conditions for 2 or 3 months. Suddenly, stored procedures called from my MVC web app or SQL Management Studio return Time Out. Queries like Select * from Table work perfect.
EDIT: Timeouts while executing Alter or Create SP queries happened too.
No proper solutions or explanations found.
Workaround: Restore old backup in a new SQL Database and change the connection string to the new Database. While the system is running in the backup, try to backup the database with issues (first close all connections to that DB like Management Studio). It may take some time and some retries. After the backup is done, restore it in a new DB and change back the connectionString. You will lose a few minutes of data and some downtime but you will have your system working again in Azure.
Any ideas about this issue in the Stored Procedures in Azure?
At first glance, this smells like a parameter sniffing issue; it is probably not related to Azure.
Check this thread for details on what the issue is, and how to resolve it: Parameter Sniffing (or Spoofing) in SQL Server
If I use a web application Web Data Administrator and I edit the stored procedures SQL query, does it recompile on it's own? (new to SQL Server and this side of the database development)
MSSQL Server does maintain a cache of query plans, but this is not the same as compiled code.
The SQL Server manages this cache and can be the source of some pain if it caches a plan that is non-optimal. Though this has happened to me less than 5 times in 15 years (and that seemed to be a problem with a particular server), its best to let SQL server handle this and not touch it.
You can force SQLServer to recompile by supplying the WITH RECOMPILE option. Same caveat applies, unless you have a substantial reason to, DONT.
SQL is a scripting language, which means the code you write is not compiled. Rather, it is stored on the server to be used later.
When you edit a stored procedure, you can execute an ALTER script, or a DROP then CREATE script. This sends the text in your Web Data Admin (or SSMS) window to the server, issuing a command that tells the server to store this new query as a procedure for later use.
So, in short, yes, if you execute an ALTER script.
I am executing a very long SQL script in SQL Server Management Studio, normally it takes a few second to be done.
But this time it is taking forever and never completes. Other people running this script has no problem.
So I wonder if there is anyway I could debug in SQL Server Management Studio to see which line in this long SQL Script is currently executing and taking forever?
Easiest way is to fire up SQL Server Profiler and trace your SQL with that. As a bonus, you'll get a lot more useful information than simply which line is causing the problem.
If Profiler doesn't give you what you want, have a go with the Activity Monitor. Find your session in the Processes part, and then pull up the details to see the last T-SQ command batch.
Is there a view or internal sp to do this?
For example, I have a sp spGoesOnForSomeTime.
If I kicked this off then some individual closes my computer down, how can I see whether this is still running or not?
I realise I can use SQL Profiler and ActivityMonitor but I ultimately want to relay this information back through a web app.
EDIT: Apologies, it is not a local connection.
If it's run under your local connection, then it will stop and roll back, so you can be confident that it is not running.
If it's running under the context of another connection, you can use the sp_who stored procedure to see all of the activity (and active connections) on the server, and the cmd column should provide you with the command. If any of the records have your procedure name in their cmd column, then that will tell you that it's executing.
You may, however, want to take a more intentional approach and set a flag of some kind (a value in a row in another table, an extended property on the database or procedure, etc.) when the procedure starts, then reset it when the procedure finishes. This would also account for scenarios where your procedure gets called from within another procedure.
If running it from your local Management Studio, the connection will be broken (closed) when SSMS closes.
Any transactions will rollback, all locks will be released. If you're in the middle of some huge data changes, your proc stops running and the connection is still closed, but the rollback will continue anyway
So no need to check based on the facts given...
Depends whether you're running it using SqlServerAgent or just via Mgmt Studio.
As #gbn said, once you disconnect then any work using that connection will stop too.
I'd say create a scheduled Job and then it's independent of your connection.
If this is part of an application requirement then I would log the start and finish of all of the calls to this stored procedure then have a view against that to show which instances of the stored procedure are currently running.
If this is for maintenance of the database then I would use sp_who or sp_who2.
EDIT:
Actually, sp_who and sp_who2 will likely show you the currently running command, not necessarily the stored procedure name itself. You can try using the system dynamic view sys.dm_exec_sql_text, but that isn't always going to be accurate either.