与直接在数据库上运行相比,从 ASP.NET MVC Web 应用程序执行 SQL 查询时,我遇到了明显的性能问题。
该查询应该检索大约 40,000 行,当直接在数据库上运行时,它会在大约 5 秒内完成。
但是,当使用以下 C# 函数从我的 Web 应用程序执行相同的查询时,大约需要 23 秒才能完成。
为什么差别这么大?
已采取的步骤:
ek_start_datetime
)的任何特定检查。此更改仅将性能提高了约 1.5 秒。public static List<Dictionary<string, string>> GetData(List<string> columns, string query)
{
List<Dictionary<string, string>> data = new List<Dictionary<string, string>>();
using (SqlConnection con = new SqlConnection(CS))
{
SqlCommand cmd2 = new SqlCommand(query, con);
cmd2.CommandType = CommandType.Text;
cmd2.CommandTimeout = 200;
con.Open();
SqlDataReader rdr = cmd2.ExecuteReader();
while (rdr.Read())
{
Dictionary<string, string> dict = new Dictionary<string, string>();
foreach (string column in columns)
{
if (rdr[column] == null)
{
dict.Add(column, "");
}
else if (column.Contains("ek_start_datetime"))
{
dict.Add(column, ((DateTime)rdr[column]).ToString("yyyy-MM-dd HH:mm:ss.fff"));
}
else if (column.Contains("_startdatetime") && DateTime.TryParse(Convert.ToString(rdr[column]), out DateTime res))
{
dict.Add(column, ((DateTime)rdr[column]).ToString("yyyy-MM-dd HH:mm:ss.fff"));
}
else if (column.Contains("_datetime") && DateTime.TryParse(Convert.ToString(rdr[column]), out DateTime res2))
{
dict.Add(column, ((DateTime)rdr[column]).ToString("yyyy-MM-dd HH:mm:ss.fff"));
}
else if (column.Contains("_date") && DateTime.TryParse(Convert.ToString(rdr[column]), out DateTime result))
{
dict.Add(column, result.ToString("yyyy-MM-dd"));
}
else
{
dict.Add(column, Convert.ToString(rdr[column]));
}
}
data.Add(dict);
}
}
return data;
}
编辑
我发送的查询是一个字符串,其全局布局为:
SELECT
tv.column1,
tv.column2,
-- ...
tv.column80,
FROM
table1 tv
WHERE
tv.actual_flag = CAST(1 AS INT)
AND tv.theme = CAST("theme1" AS varchar(10))
AND tv.year as CAST(2024 AS INT)
当我在 SSMS 中执行相同的查询并查看查询计划时,它已正确优化
以下
SET
选项有可能影响计划的重新使用
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
SET ARITHABORT ON
GO
以下两条语句来自msdn - SET ARITHABORT
将 ARITHABORT 设置为 OFF 会对查询优化产生负面影响,从而导致性能问题。
SQL Server Management Studio 的默认 ARITHABORT 设置为 ON。将 ARITHABORT 设置为 OFF 的客户端应用程序可以接收不同的查询计划,从而难以对性能不佳的查询进行故障排除。也就是说,相同的查询在 Management Studio 中执行速度很快,但在应用程序中执行速度很慢。
要将数据库设置为此,您只需在 SSMS 中使用一次
USE master
ALTER DATABASE [your_database_name] SET ARITHABORT ON WITH NO_WAIT