简体   繁体   中英

SQL Server query poor performance

We are working with an app, .NET, in which when you press a button a DevExpress form is opened and a SQL Server query is executed, so it can fill with data some comboboxes. Application is working fine in lots of customers, but in a particular one it´s taking more than a minute in loading the form. I can see in the performance monitor that SQL Server is taking a lot of CPU when I want to load the form.

I executed the query directly in SQL Server Management Studio, taking no more than a second, however I tried having a look at SQL Activity Monitor and what I can see here (not happening to other customers, same IO, same SQL, same everything) is this:

在此处输入图片说明

So the thing I can see here, that I don´t understand, is why is this query having so much executions? Why is it taking so long to retrieve data? Here it´s the execution plan of this query:

Select * 
From cuinac_pos  
Where [group] in (Select [group] 
                  From proc_groups  
                  Where Code = 13100271)

在此处输入图片说明

Thank you for any help you can give me, and please if I can give any more info do not hesitate to ask.

Once again, thanks!

AFTER ADDING THE EXECUTION PLAN SUGGESTED INDEX

在此处输入图片说明

在此处输入图片说明

EXECUTION PLAN FOR QUERY

Select count(*) 
From proc_groups 
Where Code = 13100271

在此处输入图片说明

在此处输入图片说明

Definition of the index in proc_groups:

在此处输入图片说明

Example of the code:

private static void LoadDTPurchaseHerdRelation(Int32 status, Int32 herdNumber)
        {
            try
            {
                StringBuilder sb = new StringBuilder();


                sb.Append(" Select gr.[group] as HerdId, gr.code as HerdNumber, bo.code as PurchaseCode");
                sb.Append(" From cuinac_pos bo ");
                sb.Append(" inner join proc_groups gr on bo.code=gr.code ");

                if (herdNumber == 0)
                {
                    string s1 = " Where (gr.created between '2015-12-09' And '2016-01-08') ";
                    sb.Append(s1);

                    if (status != 4)
                    {
                        string s2 = string.Format(" AND bo.purchasestatus = {0} ", status);
                        sb.Append(s2);
                    }

                    sb.Append(" order by bo.code ");
                }
                else
                {
                    string s3 = string.Format(" Where gr.code = '{0}' ", herdNumber);
                    sb.Append(s3);
                }

                DTPurchaseHerdRelation.Clear();
                using (ConnectionScope cs = new ConnectionScope())
                {
                    SqlDataAdapter adapter = new SqlDataAdapter(sb.ToString(), (SqlConnection)cs.Connection);
                    adapter.Fill(DTPurchaseHerdRelation);
                }
            }
            catch (Exception ex)
            {

            }
        }

    }
}

Execution plan for query

Select * From cuinac_pos Where [group] in (Select [group] From proc_groups Where Code = N'13100271')

在此处输入图片说明

Solved:

I finally got it by adding indexes suggested in the answer marked as correct, and adding in the code, in the queries which searched by nvarchar value "Code", an N before rhe value as suggested in comments by shriop. Thank you all for your effort!

For this query:

Select *
From cuinac_pos
Where [group] in (Select [group] From proc_groups  Where Code = 13100271 );

The optimal indexes are proc_groups(code, group) and cuinac_pos(group) . Having those indexes might help.

EDIT:

For performance, this might be better:

Select *
From cuinac_pos cp
Where exists (Select 1
              From proc_groups pg
              Where pg.Code = 13100271 and pg.[group] = cp.[group]
             );

with an index on `proc_groups(group, code)

Whenever I read something like "fast in SSMS but slow in application" I have to think about this:

http://www.sommarskog.se/query-plan-mysteries.html

This applies especially to older DBs, which exist from SQL Server version to SQL Server version and are upgraded via scripts, and where the data reading is done through Stored Procedures.

Most of the time this behaviour is solveable with a SET ARITHABORT ON as first line of your SQL code.

You can put this into you SPs directly, or set it in your application through the Connection as default.

Good luck and happy coding

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM