Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why code is maxing out the CPU while querying the database?

My C# code below checks a SQL database to see if a record matches a ClientID and a User Name. If more than 15 or more matching records are found that match, the CPU on my Windows 2008 server peaks at about 78% while the 15 records are found while the below C# code executes. The SQL Server 2008 database and software is located on another server so the problem is not with SQL Server spiking the CPU. The problem is with my C# software that is executing the code below. I can see my software executable that contains the C# code below spike to 78% while the database query is executed and the records are found.

Can someone please tell me if there is something wrong with my code that is causing the CPU to spike when 15 or more matching records are found? Can you also please tell/show me how to optimize my code?

Update: If it finds 10 records, the CPU only spikes at 2-3 percent. It is only when it finds 15 or more records does the CPU spike at 78% for two to three seconds.

//ClientID[0] will contain a ClientID of 10 characters
//output[0] will contain a User Name
char[] trimChars = { ' ' };
using (var connection = new SqlConnection(string.Format(GlobalClass.SQLConnectionString, "History")))
{
    connection.Open();
    using (var command = new SqlCommand())
    {
        command.CommandText = string.Format(@"SELECT Count(*) FROM Filelist WHERE [ToAccountName] = '" + output[0] + @"'");
        command.Connection = connection;
        var rows = (int) command.ExecuteScalar();
        if (rows >= 0)
        {
            command.CommandText = string.Format(@"SELECT * FROM Filelist WHERE [ToAccountName] = '" + output[0] + @"'");
            using (SqlDataReader reader = command.ExecuteReader())
            {
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        //Make sure ClientID does NOT exist in the ClientID field
                        if (reader["ClientID"].ToString().TrimEnd(trimChars).IndexOf(ClientID[0]) !=
                            -1)
                        {
                            //If we are here, then do something
                        }
                    }
                }
                reader.Close();
                reader.Dispose();
            }
        }
        // Close the connection
        if (connection != null)
        {
            connection.Close();
        }
    }
}
like image 394
fraXis Avatar asked Dec 10 '25 13:12

fraXis


1 Answers

You can decrease the number of database access from 2 to 1 if will remove first query, it is not necessary.

using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = connection.CreateCommand())
{
    command.CommandText = "SELECT ClientID FROM dbo.Filelist WHERE ToAccountName = @param"; // note single column in select clause
    command.Parameters.AddWithValue("@param", output[0]); // note parameterized query

    connection.Open();
    using (SqlDataReader reader = command.ExecuteReader())
    {  
        while (reader.Read()) // reader.HasRow is doubtfully necessary
        {
            // logic goes here
            // but it's better to perform it on data layer too

            // or return all clients first, then perform client-side logic
            yield return reader.GetString(0);
        }
    } // note that using block calls Dispose()/Close() automatically
}
like image 173
abatishchev Avatar answered Dec 12 '25 02:12

abatishchev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!