首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用实体框架改进更新40000条记录的优势

使用实体框架改进更新40000条记录的优势
EN

Code Review用户
提问于 2018-03-22 04:22:06
回答 2查看 91关注 0票数 -1

我有两张桌子电路和标签,

代码语言:javascript
复制
Circuit 
------------------
Id    Name  Path 

Tag
-----------
Id Name Circuit_Id

现在,我必须循环遍历所有的标签,并更新每个标签,其中有匹配的路径和名称(电路路径和标签名称)。

我正在做这件事,效果很好,但它真的很慢。有没有办法提高速度。

代码语言:javascript
复制
foreach (var tag in allPDUTags)
{
    var removedUnderScoreLast = tag.Path.Remove(tag.Path.LastIndexOf('_'));
    var removedUnderScoreLastButOne = removedUnderScoreLast.Remove(removedUnderScoreLast.LastIndexOf('_'));

    var circuitId = _context.Circuits.Where(c => c.Name == removedUnderScoreLastButOne).FirstOrDefault().Id;

    tag.Circuit_Id = circuitId;


    _counter++;

    if ((_counter % 1000) == 0)
    {
        Console.WriteLine($"Updated {_counter} of {totalsTags} Tags");
    }


}
EN

回答 2

Code Review用户

发布于 2018-03-22 20:06:26

代码语言:javascript
复制
var circuitId = _context.Circuits.Where(c => c.Name == removedUnderScoreLastButOne).FirstOrDefault().Id;

这一行实际上是循环中的一个联接,这意味着您将查询数据库中的每个标记。因此,您有40k额外的查询,这似乎是速度慢的最大原因。

我会专注于把连接移出你的循环。有几种方法你可以做到这一点。

  1. 将allPDUTags更改为电路和标记之间连接的结果。
  2. 如果您可以退出实体框架,编写SQL以高效的方式更新行应该是相对简单的,因为它们都在数据库表中。我不确定您正在使用的DBMS,因此我无法提供示例代码。
  3. 快速而肮脏的做法是把电路列表放进内存中。调用_context.Circuits.ToList()会将它们全部放入内存中,然后与循环中的列表进行比较。假设电路足够小,可以装进内存。这个选项不会很好的扩展,我也不会推荐它。

我将仔细研究为什么Circuit.Path和tag.Name首先需要同步。可能有历史原因,也可能是在两个不同的数据库/系统中,但如果它们位于同一个应用程序中,我将强烈考虑将数据库规范化,或者添加约束,以避免首先进行同步。

票数 1
EN

Code Review用户

发布于 2018-03-23 12:33:12

这是一种TSQL方法。应该会很快的。

代码语言:javascript
复制
declare @Circuit table (id int identity primary key, name varchar(20));
declare @Tag table     (id int identity primary key, path varchar(40), circuitID int);
insert into @tag (path) values ('asld_aslkjf_alskd'), ('asxx_askjf_alsyd_ lasdj');
insert into @Circuit (name) values ('asld'), ('asxx_askjf');

select * from @tag;

update t 
set t.circuitID = c.id 
from @tag t 
join @Circuit c
  on c.name = reverse(SUBSTRING(REVERSE(t.path), CHARINDEX('_', REVERSE(t.path), CHARINDEX('_', REVERSE(t.path)) + 1) + 1, 100))
where t.circuitID <> c.id or t.circuitID is null;

select * from @tag
票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/190162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档