I am remotely selecting results from a custom production database with a criteria of around three minutes from a C# application.
Every time the select command is executed, the server PC that I am using CPU goes up to around 50%. But surely, the load should be on the database that I am connecting to?
Why would the C# application rocket to 50% until the data is retrieved for reading?
Some background
Here is some code I am using.
OdbcConnection remoteConn = new OdbcConnection(ConfigurationManager.ConnectionStrings["remoteConnectionString"].ToString());
remoteConn.Open();
OdbcCommand remoteCommand = new OdbcCommand();
remoteCommand.Connection = remoteConn;
using (remoteConn)
{
string localSql = "";
string remoteSql = "select * from tracking where last_update > 212316247440000000"; // Julian No = 2015-07-12 11:24:00
remoteCommand.CommandText = remoteSql;
OdbcDataReader remoteReader;
remoteReader = remoteCommand.ExecuteReader();
while (remoteReader.Read())
{
for (int i = 0; i < 68; i++)
{
localSql += ",'" + remoteReader[i].ToString() + "'";
}
}
}
I ran a performance and diagnostic test on the application and it yielded this result.
How, if any, can I reduce this CPU load or even eradicate it completely. It is completely out of the ordinary and I have no clue on how to go about it.
Thanks
SQL Server executes fewer instructions per row when using batch mode over row mode. By reducing the number of instructions when using batch mode, queries typically use less CPU than row mode queries. Therefore, if a system is CPU bound, then batch mode might help reduce the environment's CPU footprint.
Thanks for the information, Dan. Here are my thoughts...
I believe the primary reason why your app is consuming so much CPU is because of the drivers you are using.
Since you are connecting to an SQL Server database, you should use the SQL Server drivers which know how to optimize transportation of data between client and server.
To use the appropriate drivers, make sure you use the SqlConnection
, SqlCommand
, etc.
This will allow SQL Server to stream the results to your client as you query the data reader.
Secondly, do not use the ExecuteReader()
method on the DbCommand
object. One of the many wonderful features unique to the SQL Server drivers is the ExecuteReaderAsync()
method.
Since this command is an IO-bound operation (not compute-bound) then there is no need to block the calling thread. When the result come back they will arrive on an IO completion thread.
Here is a code sample of what your code might look like after the change.
using (var remoteConn = new SqlConnection(ConfigurationManager.ConnectionStrings["remoteConnectionString"].ToString()))
{
remoteConn.Open();
using (var remoteCommand = new SqlCommand())
{
remoteCommand.Connection = remoteConn;
string localSql = "";
string remoteSql = "select * from tracking where last_update > 212316247440000000"; // Julian No = 2015-07-12 11:24:00
remoteCommand.CommandText = remoteSql;
var remoteReader = await remoteCommand.ExecuteReaderAsync();
while (remoteReader.Read())
{
for (int i = 0; i < 68; i++)
{
localSql += ",'" + remoteReader[i].ToString() + "'";
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With