假设我的SQL数据库中有两个表。 1.一张中等大小的表,有数千条名为MyTable1的记录 2.一张包含数百万条记录(并且日益增长)的大型表格,名为MyTable2
MyTable1和MyTable2都有一个名为Hash的属性,可以是相同的。
我希望找到最有效的方法来使用Linq to Entities迭代MyTable1并找到MyTable2中具有相同Hash并保存到另一个表中的所有记录。以下是代码外观的简化视图。
using(var db = new context()) {
var myTable1Records = db.MyTable1.Select(x => x);
foreach(var record in myTable1Records) {
var matches = db.MyTable2.Where(y => y.Hash.Equals(record.Hash)).Select(y => y);
foreach(var match in matches) {
// Add match to another table
}
}
}
随着MyTable2的大小每天都在变大,我看到这段代码的性能显着下降。我正在尝试有效处理这种情况的一些想法是:
我很想知道在这种情况下你是否有其他技术或魔法子弹有效。谢谢!
答案 0 :(得分:1)
您有一个名为Hash
的媒体资源。使用它作为哈希!将第一个表存储在由Dictionary
键入的Hash
中,然后遍历第二个表格,检查Dictionary
中的匹配项,再次按Hash
键入。
或者,更好的是,使用LINQ:
var matches = db.MyTable1.Intersect(db.MyTable2);
如果您需要进行自定义比较,请创建IEqualityComparer
。 (我假设您正在进行某种类型的投影,Select(x => x)
是占位符,用于此问题。)
或者,更好的是,在存储过程或视图中完全在数据库中进行此操作可能会更好。你基本上是做JOIN
但是用C#来做。您需要承担从数据库到客户端应用程序的往返时间成本,以便在数据库服务器上完成所有操作。
答案 1 :(得分:1)
你在这里做的是执行内连接。通过使用查询提供程序,您甚至可以确保此工作在数据库端完成,而不是在应用程序的内存中完成;你只会拉下匹配的结果,不再:
var query = from first in db.MyTable1
join second in db.MyTable2
on first.Hash equals second.Hash
select second;
答案 2 :(得分:1)
我建议留在SQL Server中。视图或聚簇索引可能是最好的方法。
以下是一些用于阅读索引主题的资料来源:
答案 3 :(得分:1)
可能索引你的哈希列可以提供帮助。假设Hash是char或varchar类型,索引可以支持的最大长度为900字节。
CREATE NONCLUSTERED INDEX IX_MyTable2_Hash ON dbo.MyTable2(Hash);
对于索引varchar的性能,您可能需要在此处查看 SQL indexing on varchar