1 linq database sql-server entity-framework dapper
我在我的项目中使用带有 LINQ 和 SQL Server 的 EF 很长时间了。
我正在寻找一种方法来提高我对数据库的请求的性能。我读了很多关于 Dapper 和程序的文章,它比 EF 快。我将 Dapper 添加到项目中,我添加了程序......但我的测试显示出奇怪的结果。EF 和 Dapper 以及存储过程的结果几乎相同——没有任何好处。
首先,我检查了一个有很多 Join 的请求。我在 Dapper、Procedure 和 EF 之间得到了几乎相同的结果。然后我决定用一张没有关系的简单表做一个测试。
我有表格邮政编码。有 43200 条记录。
我使用 EF、Dapper、存储过程和 SQL Server 中的请求对 1 000 条记录、10 000 条记录和 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;
}
Run Code Online (Sandbox Code Playgroud)
英孚
var zip = db.ZipCodes.AsNoTracking().Take(43200).ToList();
Run Code Online (Sandbox Code Playgroud)
存储过程
ALTER PROCEDURE [dbo].[ZIPTest]
AS
BEGIN
SELECT TOP (43200)
[Zip], [City], [State], [Latitude], [Longitude], [TimeZone], [DST]
FROM
[dbo].[ZipCodes]
END
Run Code Online (Sandbox Code Playgroud)
随时间在 SQL Server 中请求
SELECT GETDATE();
SELECT TOP (43200)
[Zip], [City], [State], [Latitude], [Longitude], [TimeZone], [DST]
FROM
[dbo].[ZipCodes]
SELECT GETDATE();
Run Code Online (Sandbox Code Playgroud)
在代码中我使用秒表
string first = "", second = "", third="";
System.Diagnostics.Stopwatch swatch = new System.Diagnostics.Stopwatch();
swatch = new Stopwatch();
swatch.Start(); Dapper request;
Run Code Online (Sandbox Code Playgroud)
然后
swatch.Stop();
first = swatch.Elapsed.ToString(@"m\:ss\.fff");
swatch = new Stopwatch();
swatch.Start();
Run Code Online (Sandbox Code Playgroud)
等等
结果:(以毫秒为单位)
1000 10000 43200
-------------------------------------------------
EF 107 1085 4527
Dapper 139 1084 4036
Stored procedure 129 1089 4519
SQL query 8 17 60
Run Code Online (Sandbox Code Playgroud)
EF、Dapper 和存储过程之间的差异非常小。为什么会这样?
为什么 SQL Server 中的查询如此之快,而来自代码的请求却慢了 15-70 倍?
好还是不好?
使用 EF 表现出性能问题的代码不会神奇地与 Dapper 或 ADO + Sprocs 一起运行得更快。要深入了解性能问题,您需要调查并消除性能问题的原因。
在顶层,这些性能问题源于两个核心问题。
我关注的关键事项:(作为开始,还有很多项目,但这些是最大的胜利)
延迟加载:这是从一组相关实体加载代码的地方,但这样做时,代码在初始加载后访问这些相关实体,导致这些相关实体中的每一个都被单独加载。
.Include()) 来加载这些集合。更好的解决方法是使用.Select()仅加载相关代码所需的属性。.ToList():.ToList()随着系统的成熟,错误的调用会导致巨大的性能问题,因为开发人员遇到了 EF 的问题,而该问题通过调用.ToList. 通常,当开发人员尝试在.Where()or.Select()表达式中调用方法时会出现这些。EF 无法理解这些以传递 SQL 等效项,因此添加将其.ToList()转换为 Linq2Object 并“ta-da”它可以工作!
.ToList()在 a.ToList()之前找到a.Select()或.Where()等的实例并标记任何情况。.ToList()会导致 EF 错误。客户端分页 + 实体:没有适当样本数据的另一个开发罪。编写的查询有效地返回所有数据,而不考虑记录总数。数据在带有分页的网格中显示在客户端,这“有效”但真的很慢。当数据库中只有 200 行时,它运行良好,但现在爬行了 50,000。(而且只会变得更糟)
.ToList()or .Skip()+.Take()吗?这些方法是否返回实体或视图模型?数据库索引:是否对数据库进行了监控和维护?是否有索引和索引维护?对于 SQL Server,是否正在备份数据库并使其 Tx 日志缩小?Code First 实现充斥着这些问题,其中系统在不考虑后备数据库的情况下启动。随着系统的增长,不会关心支持它的数据库。
Guid.New()没有任何索引维护。数据库没有设置索引。事务日志 (.LDF) 比数据库文件 (.MDF) 等大 15 倍,等等。| 归档时间: |
|
| 查看次数: |
3932 次 |
| 最近记录: |