Disparity between SqlReader execution times on same .NET project but different computers - c#

I'm working on a team project that reads data from a MSSQL server. We are using an asynchronous call to fetch the data.
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
SqlCommand cmdData = new SqlCommand("get_report", conn);
cmdData.CommandType = CommandType.StoredProcedure;
conn.Open();
IAsyncResult asyResult = cmdData.BeginExecuteReader();
try
{
SqlDataReader drResult = cmdData.EndExecuteReader(asyResult);
table.Load(drResult);
}
catch (SqlException ex)
{
throw;
}
The project itself uses TFS source control with gated check-ins, and we have verified that both computers are running the exact same version of the project. We are also using the same user login and executing the stored procedure with the exact same parameters (which are not listed for brevity).
The stored procedure itself takes 1:54 to return 42000 rows under SQL Server Management Studio. While running on Windows 7 x86, the .NET code takes roughly the same amount of time to execute as on SSMS, and the code snippet above executes perfectly. However, on my computer running Windows 7 x64, the code above encounters an error at the EndExecuteReader line at the 0:40 mark. The error returned is "Invalid Operation. The connection has been closed."
Adding cmdData.CommandTimeout = 600 allows the execution to proceed, but the data takes over 4 minutes to be returned, and we are at a loss as to explain what might be going on.
Some things we considered: my computer has .NET 4.5 Framework installed, is running 64-bit OS against 32-bit assemblies, may be storing information in the local project file that isn't being synchronized to the TFS server. But we can't seem to figure out exactly what might actually be causing the disparity in times.
Anyone have any ideas as to why this disparity exists or can give me suggestions of where to look to isolate the problem?

Invalid Operation error is received when EndExecuteReader was called more than once for a single command execution, or the method was mismatched against its execution method.

Related

OleDBConnection.Close() very slow on server

I am working on a few applications which connect to an MS Access database backend (.mdb) to read/insert/update records.
Everything is working fine, but I noticed that my db operations were quite slow. The backend is accessed by other users, but I still get the issue when querying a copy of the access file which no one else connects to.
I managed to narrow this down so that I can now see the offending code is the line
connection.Close()
Called on an open OleDBConnection which has just executed some query, e.g:
var con = new OleDbConnection(connectionString);
con.Open();
var query = "SELECT * FROM subGRCReceived WHERE GRVNo=#grv";
var args = new DynamicParameters();
args.Add("#grv", grvNumber);
// Using Dapper
var pallets = (List<Pallet>)con.Query<Pallet>(query, args);
con.Close(); // This is often taking between 7-10 seconds
I can confirm that this is occurring when using using/con.Close()/con.Dispose(), and using or not using Dapper makes no difference.
I did notice that this only seems to happen with web based prjojects (ASP MVC or WCF soap service) and not Console applications. The issue seems to be intermittent, but occurs frequently enough for it to be a pain for the user (especially when navigating to a page uses 2-3 db queries, as this can take as long as 20 seconds to load).
The problem does not lie with the code itself, as I am able to host the same application on my laptop on the same network as the server and the speed is perfect (~200ms per request). See the specs of the 2 machines below:
Laptop Details:
Processor : Intel Core i7-6700HQ CPU # 2.60GHz
RAM : 16.0 GB
OS : Windows 10 x64
Server Details
Processor : Intel Xeon CPU E5-2603 v4 # 1.70GHz (2 processors)
RAM : 32.0 GB
OS : Windows Server 2012 x64
Setup
32 bit MS Access 2016
2016 Microsoft ACE OLE Engine
64 it OS
What I have tried
Moved the database to same folder as application
Disabled antivirus (ESET)
Increased the MaxBufferSize key value from 0 in Access Connectivity Engine in the registry (does this need a restart?)
Measure the time it takes to run GC.Collect() before calling Close() to ensure it is not the garbage collector
Workarounds
Threading
I tried calling Close() from a new thread, which seemed to work after 1 request, but if I try accessing the application again I am getting unhandled win32 errors on the server (Even though I wrapped my thread and connection.Close() calls in try/catch. I suspect this might be failing because the thread might take 7 seconds to close the connection, but the IIS worker process gets terminated before that, so there may be some missing resources that Close() needs. It might be nice if I could get this working, but I understand that this i bad practise in MVC, and also does not actually solve the issue.
Persistent Connection
I could also just have 1 OleDBConnection and keep it open throughout the session. I did this with the WCF service (1 connection per request) and it works find, however I get the feeling that it wont work quite as well with ASP MVC, and after doing a bit of research it looks like this is not a good idea.
I have been struggling with this for a week now and its driving me crazy, does anyone have any advice at all?

C# Sql LocalDB Application Slow Performance

I am completely new sql/database applications and am trying out a simple contact management applicaton using Visual Studio 2015 C#. I am using 'SQL Express LocalDB'. I have read on google that it is meant for development purpose, but microsoft also mentions that it could be used for production purpose too.
My problem is that when I try out the application from my developement system, the application first time takes few seconds to load but after that every query runs quickly. When I tried this on one my friends system, it takes time everytime I try to use any query. The database is just with 20-30 records.
I create new connection using 'new SqlConnection' and then execute command created by 'new SqlCommand' and after executing query I close the connection.
Here is the code snippet from my app
SqlConnection sqlConnection = new SqlConnection(#"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename = ""C:\ContactsDB.mdf""; Integrated Security = True; Connect Timeout = 30";);
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.Connection = sqlConnection;
sqlCmd.CommandText = "SELECT Id, first_name, last_name from ContactsMaster ORDER BY first_name";
sqlConnection.Open();
SqlDataReader reader = sqlCmd.ExecuteReader();
try
{
while (reader.Read())
{
ListViewItem lvi = new ListViewItem(reader["first_name"]);
listViewItems.Add(lvi);
lvi.SubItems.Add(reader[0].ToString());
}
}
finally
{
reader.Close();
}
sqlConnection.Close();
Q. Should I keep the connection open all the time while app is running? I don't think this should be suggested. As if app crashes database can get corrupt.
One of the backdrop which ppl saying that LocalDB closes the connection every new milliseconds. So should I keep pinging the database every few milliseconds? Or I should not use localdb in production at all?
I want to make the app such that the requirement goes really low regaridng the database prerequisites. Like LocalDB installation is really seamless.
I have not used SQL Server Express, does Express installation is also seamless like LocalDB and can I use the connection string like LocalDB in Express too, giving the .mdf filename directly?
localdb has auto shutdown. default is 5 min. you can set it to higher value (ie: 12hour).
max is 65535 min.
see: How to prevent SQL Server LocalDB auto shutdown?
also sqlexpress autoshutdown is 1hour if im not wrong.
symptoms on my pc:
first open is 10- 30 seconds slow. if i reopen app right after it is below 1 second. if i wait for a while it is slow again
There are many things to take in count for ddbb performance, it's not a simple question. For such small amount of records there shouldn't be performance problems. Try storing the ddbb files in another disk different from OS disk, and even better, place data file and log file in different disks too.
About your question, connections must be always closed and disposed properly in a finally block or inside a using block.
Sql Express is very easy to install, and also use a connection string, been the biggest difference that it can be used across the network.
Finally moved to SQLite and that is much faster in compare to SQLLocalDB.

How to make Oracle return an error when i give it invalid SQL?

I've been using the Oracle ODP.NET, Managed Driver to issue queries from C#.
There were many queries i wrote that took forever to return any data; like it was ignoring my row limiting clauses:
SELECT TOP 10 *
FROM Customers
or
SELECT *
FROM Customers
FETCH FIRST 10 ROWS ONLY
It was like Oracle was ignoring my 10 row limit, and started returning everything - because it was taking forever to return. Eventually i realized that it wasn't that the query was busy returning a lot of data; it was that the query SQL was invalid.
When you issue invalid SQL to Oracle, it will not fail with an error.
select top 10 * from customers;
select 'Hello, world!';
select sysdate from duel;
select sysdate fro;
Ceilings make pie and markers drive the ocean with their feet
Oracle will sit there waiting for the command timeout to expire.
IDbCommand cmd = connection.CreateCommand();
cmd.CommandText = "Ceilings make pie and markers drive the ocean with their feet";
IDataReader rdr = cmd.ExecuteReader(); //<--will wait forever
while (rdr.Read())
{
//...
}
I eventually realized that the Oracle.ManagedDataAccess.Client.OracleCommand object (bizzarly) has no CommandTimeout; it defaults to running forever. Once i changed it to a more reasonable 30 seconds, i start seeing the error message:
ORA-12537: Network Session: End of file
Is there an option in the Oracle ODP.NET, Managed Driver, or in the connection string, or in the OracleCommand to tell the server to throw an error if there is an error in my SQL statement?
Bonus Chatter
Oracle provides two database drivers for ADO.net
one is an ADO.net managed wrapper around the 100MB native database drivers that you must already have installed (Oracle.DataAccess)
the other is a standalone 3.8 MB driver, written in pure managed code, that has no other dependencies (Oracle.ManagedDataAccess)
Microsoft had created an Oracle driver, which is included in the .NET Framework. But that driver is deprecated, and no longer functions in .NET 4.5 requires the full Oracle client software version 8.1.7 or greater to be installed (System.Data.OracleClient)

SqlClient.SqlException: The wait operation timed out

I'm currently trying to create a large amount of test data with numerous insert statements using code similar to below...
using (var connection = new SqlConnection(_connectionString))
{
using (var command = new SqlCommand(query.ToString(), connection))
{
try
{
connection.Open();
command.ExecuteNonQuery();
return true;
}
catch (Exception e)
{
......
}
}
}
My problem is that I keep getting an error
The wait operation timed out
and yet when I run the SQL statement that failed from within SQL Server Management Studio, it executes in less than 100ms. The error always seems to occur whilst inserting into the largest table which currently has 47,738,476 rows and is 1,970,696Kb in size.
I'm using:
Microsoft SQL Server 2012 (SP1) - 11.0.3128.0 (X64)
Express Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
Any, help would be most appreciated.
Disclaimer: It may not be an answer but it solves the problem :)
Use Redgate Sql Data Generator
http://www.red-gate.com/products/sql-development/sql-data-generator/
It is not free but it is fully functional trial for some days and it will do the work for you what i want to
achieve.
It had lot of option and generate real looking data.

SQL-CLR stored procedure doesn't return value

I looked through Stackoverflow and found almost identical question here. It was asked a year ago and nobody answered it yet. Maybe I'll be more lucky than user1038334 and somebody will help me.
I have a SQL CLR stored procedure which works fine for days until something weird happens. My stored proc updates tables and returns a value as a result code. So by looking at this value I can decide if something went wrong. The problem is in receiving this result value. C# code throws an exception at a point of receiving a return value.
var returnValue = new SqlParameter {Direction = ParameterDirection.ReturnValue};
command.Parameters.Add(returnValue);
connection.Open();
command.ExecuteNonQuery();
return (int)returnValue.Value; //<-- here is an exception
And the funniest thing is that if I connect SQL Profiler, catch the query and then execute this query inside of SQL Server Management Studio I still can get a result value without any problems:
DECLARE #RC INT
EXECUTE #RC = MyClrStoreProc
SELECT #RC
Once I republish the CLR assembly or restart SQL Server everything gets fixed.
I'm pretty sure there should be a reason for such weird behaviour but I can't find.
SQL Server version: Microsoft SQL Server Developer Edition (64-bit) - v.10.50.1765.0
Host OS version: Microsoft Windows NT 6.1 (7601)
.Net version: v4.0.30319
Any help would be greatly appreciated.
This is a SQL Server bug and Cumulative Update package 8 fixes the issue.

Categories

Resources