SQL 服务器查询性能不佳
SQL Server query poor performance
我们正在使用 .NET 应用程序,当您按下按钮时,会打开 DevExpress 表单并执行 SQL 服务器查询,因此它可以填充一些组合框的数据。应用程序在很多客户中运行良好,但在特定客户中,加载表格需要一分多钟。当我要加载表单时,我可以在性能监视器中看到 SQL 服务器占用了大量 CPU。
我直接在 SQL Server Management Studio 中执行查询,用时不超过一秒钟,但是我尝试查看 SQL Activity 监视器以及我能看到的内容这里(其他客户没有发生,相同的 IO,相同的 SQL,相同的一切)是这样的:
所以我在这里看到的是我不明白的是为什么这个查询有这么多的执行?为什么检索数据需要这么长时间?
这是此查询的执行计划:
Select *
From cuinac_pos
Where [group] in (Select [group]
From proc_groups
Where Code = 13100271)
谢谢你能给我的任何帮助,如果我能提供更多信息,请不要犹豫。
再次感谢!
添加执行计划建议索引后
查询的执行计划
Select count(*)
From proc_groups
Where Code = 13100271
proc_groups中索引的定义:
代码示例:
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)
{
}
}
}
}
查询的执行计划
Select * From cuinac_pos Where [group] in (Select [group] From proc_groups Where Code = N'13100271')
已解决:
我最终通过添加标记为正确的答案中建议的索引,并在代码中添加,在按 nvarchar 值 "Code" 搜索的查询中,在评论中建议的 rhe 值之前添加 N虾。谢谢大家的努力!
对于此查询:
Select *
From cuinac_pos
Where [group] in (Select [group] From proc_groups Where Code = 13100271 );
最优指标为proc_groups(code, group)
和cuinac_pos(group)
。拥有这些索引可能会有所帮助。
编辑:
为了性能,这可能更好:
Select *
From cuinac_pos cp
Where exists (Select 1
From proc_groups pg
Where pg.Code = 13100271 and pg.[group] = cp.[group]
);
在`proc_groups(group, code)
上有一个索引
每当我读到类似 "fast in SSMS but slow in application" 的内容时,我都必须考虑一下:
http://www.sommarskog.se/query-plan-mysteries.html
这尤其适用于从SQL服务器版本存在到SQL服务器版本并且通过脚本升级并且通过存储过程完成数据读取的旧数据库。
大多数情况下,可以通过将 SET ARITHABORT ON
作为 SQL 代码的第一行来解决此行为。
你可以直接把它放到你的SP中,或者默认通过Connection在你的应用程序中设置它。
祝你好运,编码愉快
我们正在使用 .NET 应用程序,当您按下按钮时,会打开 DevExpress 表单并执行 SQL 服务器查询,因此它可以填充一些组合框的数据。应用程序在很多客户中运行良好,但在特定客户中,加载表格需要一分多钟。当我要加载表单时,我可以在性能监视器中看到 SQL 服务器占用了大量 CPU。
我直接在 SQL Server Management Studio 中执行查询,用时不超过一秒钟,但是我尝试查看 SQL Activity 监视器以及我能看到的内容这里(其他客户没有发生,相同的 IO,相同的 SQL,相同的一切)是这样的:
所以我在这里看到的是我不明白的是为什么这个查询有这么多的执行?为什么检索数据需要这么长时间? 这是此查询的执行计划:
Select *
From cuinac_pos
Where [group] in (Select [group]
From proc_groups
Where Code = 13100271)
谢谢你能给我的任何帮助,如果我能提供更多信息,请不要犹豫。
再次感谢!
添加执行计划建议索引后
查询的执行计划
Select count(*)
From proc_groups
Where Code = 13100271
proc_groups中索引的定义:
代码示例:
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)
{
}
}
}
}
查询的执行计划
Select * From cuinac_pos Where [group] in (Select [group] From proc_groups Where Code = N'13100271')
已解决:
我最终通过添加标记为正确的答案中建议的索引,并在代码中添加,在按 nvarchar 值 "Code" 搜索的查询中,在评论中建议的 rhe 值之前添加 N虾。谢谢大家的努力!
对于此查询:
Select *
From cuinac_pos
Where [group] in (Select [group] From proc_groups Where Code = 13100271 );
最优指标为proc_groups(code, group)
和cuinac_pos(group)
。拥有这些索引可能会有所帮助。
编辑:
为了性能,这可能更好:
Select *
From cuinac_pos cp
Where exists (Select 1
From proc_groups pg
Where pg.Code = 13100271 and pg.[group] = cp.[group]
);
在`proc_groups(group, code)
上有一个索引每当我读到类似 "fast in SSMS but slow in application" 的内容时,我都必须考虑一下:
http://www.sommarskog.se/query-plan-mysteries.html
这尤其适用于从SQL服务器版本存在到SQL服务器版本并且通过脚本升级并且通过存储过程完成数据读取的旧数据库。
大多数情况下,可以通过将 SET ARITHABORT ON
作为 SQL 代码的第一行来解决此行为。
你可以直接把它放到你的SP中,或者默认通过Connection在你的应用程序中设置它。
祝你好运,编码愉快