【发布时间】:2019-08-07 21:38:21
【问题描述】:
我的项目中长期使用带有 LINQ 和 SQL Server 的 EF。
我正在寻找一种方法来提高我对 DB 的请求的性能。我读了很多关于 Dapper 和 Procedures 的文章,它比 EF 更快。我将 Dapper 添加到项目中,我添加了程序....但是我的测试显示了奇怪的结果。 EF 和 Dapper 以及存储过程的结果几乎相同 - 没有任何好处。
首先,我检查了一个包含很多 Join 的请求。我在 Dapper 和 Procedure 和 EF 之间得到了几乎相同的结果。然后我决定用一个没有关系的简单表进行测试。
我有表格邮政编码。有43200条记录。
我在 SQL Server 中使用 EF、Dapper、存储过程和请求对 1000 条记录、10000 条记录和 43200 条记录进行了测试。
小巧玲珑
string query =
"SELECT TOP (43200) [Zip]\r\n ,[City]\r\n ,[State]\r\n ,[Latitude]\r\n ,[Longitude]\r\n ,[TimeZone]\r\n ,[DST]\r\n FROM [dbo].[ZipCodes]";
using (IDbConnection connection = new SqlConnection(_connectionString))
{
var result = connection.QueryAsync<ZipCodes>(query).Result.ToList();
return result;
}
EF
var zip = db.ZipCodes.AsNoTracking().Take(43200).ToList();
存储过程
ALTER PROCEDURE [dbo].[ZIPTest]
AS
BEGIN
SELECT TOP (43200)
[Zip], [City], [State], [Latitude], [Longitude], [TimeZone], [DST]
FROM
[dbo].[ZipCodes]
END
SQL Server 中的请求与时间
SELECT GETDATE();
SELECT TOP (43200)
[Zip], [City], [State], [Latitude], [Longitude], [TimeZone], [DST]
FROM
[dbo].[ZipCodes]
SELECT GETDATE();
在我使用秒表的代码中
string first = "", second = "", third="";
System.Diagnostics.Stopwatch swatch = new System.Diagnostics.Stopwatch();
swatch = new Stopwatch();
swatch.Start(); Dapper request;
然后
swatch.Stop();
first = swatch.Elapsed.ToString(@"m\:ss\.fff");
swatch = new Stopwatch();
swatch.Start();
等等
结果:(以毫秒为单位)
1000 10000 43200
-------------------------------------------------
EF 107 1085 4527
Dapper 139 1084 4036
Stored procedure 129 1089 4519
SQL query 8 17 60
EF、Dapper 和存储过程之间的区别非常小。为什么会这样?
为什么 SQL Server 中的查询如此之快,而来自代码的请求却慢了 15-70 倍?
好还是不好?
【问题讨论】:
-
基准测试很难。对于初学者:这是一个发布版本吗?您是否使用了基准测试框架?还有更多...
-
原始 SQL 查询和存储过程缺少很多东西 - 将数据从服务器实际传输到 C# 代码所需的时间、编写和执行模型类的时间、迭代在结果集上,将原始 SQL 数据转换为 C# 类和实例 - 这是 EF 和 Dapper 都会为您处理的基本“胶水”代码。您在这里将苹果与大象进行比较 - 这不是一个非常公平和现实的比较......
-
我希望 SQL Server 查询执行和数据传输的成本与这些情况相同。 SQL 查询和 ORM 之间的差异反映了客户端 ORM 处理的成本。如果您使用没有对象映射的 SqlCommand/Sqldatareader,您可能会在应用代码中看到与 SQL 查询类似的性能。
标签: sql-server database entity-framework linq dapper