我有两张桌子电路和标签,
Circuit
------------------
Id Name Path
Tag
-----------
Id Name Circuit_Id现在,我必须循环遍历所有的标签,并更新每个标签,其中有匹配的路径和名称(电路路径和标签名称)。
我正在做这件事,效果很好,但它真的很慢。有没有办法提高速度。
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");
}
}发布于 2018-03-22 20:06:26
var circuitId = _context.Circuits.Where(c => c.Name == removedUnderScoreLastButOne).FirstOrDefault().Id;这一行实际上是循环中的一个联接,这意味着您将查询数据库中的每个标记。因此,您有40k额外的查询,这似乎是速度慢的最大原因。
我会专注于把连接移出你的循环。有几种方法你可以做到这一点。
我将仔细研究为什么Circuit.Path和tag.Name首先需要同步。可能有历史原因,也可能是在两个不同的数据库/系统中,但如果它们位于同一个应用程序中,我将强烈考虑将数据库规范化,或者添加约束,以避免首先进行同步。
发布于 2018-03-23 12:33:12
这是一种TSQL方法。应该会很快的。
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 @taghttps://codereview.stackexchange.com/questions/190162
复制相似问题