我有两种形式的记录或数据。一个是库存记录,另一个是产品。
库存记录和产品记录都将代码值存储在单独的表中。每条记录都有一个值记录,并且是外键输入主表。
我正在尝试 不 来编写此代码,因为从性能角度来看,我知道它会运行数天。
public void test(product _Product)
{
DBDataContext db = new DBDataContext();
var ProductCodes = db.tbl_ProdCodeValues.Where(x=>x.productID == _Product.productID);
foreach (var code in ProductCodes)
{
var matches = db.InventoryCodeValues.Any(x => x.InventoryValue.ToLower().Contains(code.ProdCodeValue));
}
}
将一组值与另一组值进行比较的最佳方法是什么。如果您认为任务或多线程方法也会提高性能,请告诉我。
每个产品可能有大约1-1000个值,而库存总是有超过100万个值,并且仍然会增长。因此,性能是关键,因为数学会告诉你正在进行大量的比较。如果需要,我还可以将查询从LINQ移动到SQL到T-SQL存储过程。
答案 0 :(得分:1)
您的foreach
就像Select
。
var ProductCodes = db.tbl_ProdCodeValues.Where(x=>x.productID == _Product.productID);
var withMatches =
ProductCodes
.Select(code => new {
code,
matches = db.InventoryCodeValues.Any(x => x.InventoryValue.ToLower().Contains(code.ProdCodeValue))
});
现在所有这些都转移到了数据库。查看查询计划,看看这是否已经可以接受,或者我们是否需要调整它。由于非SARGable谓词,这可能是一个讨厌的交叉产品加过滤器。
InventoryCodeValues
的格式是什么?这是一个分隔列表吗?如果将列表拆分为行,则可以使用简单的==
谓词,并使此查询以线性时间而非二次时间运行。
答案 1 :(得分:1)
将一组值与另一组值进行比较的最佳方法是什么 收集价值观。
建议的方法包括创建合并两种类型记录的列表,并根据匹配标准对合并列表进行排序。
排序后,您将按顺序识别和处理匹配。 在下面的代码中,我假设比较的代码值是字符串。
public class Member
{
internal string Key ;
internal int Source ;
internal object DataObject ;
internal Member(string key,string source,object dataobject)
{ // source identifies the source, e.g "P" for Prod and "I" for Inventory
Key = key ;
Source = Source ;
DataObject = dataobject
}
}
// create and fill the merged list
List<Member> list = new List<member>();
for (int i=0;i<db.tbl_ProdCodeValues.Count;i++)
{
string prodcodevalue = ... ; // set the value here
object prodcodeobject= ... ; // set the record object here
list.Add(new Member(prodcodevalue,1,prodcodeobject) ;
}
for (int i=0;i<db.tbl_InventoryCodeValues.Count;i++)
{
string inventorycodevalue= ... ; // set the value here
object inventorycodeobject= ... ; // set the record object here
list.Add(new Member(inventorycodevalue,2,inventorycodeobject) ;
}
// sort the merged list
list.Sort(delegate(Member x, Member y) { return (x.Key+" "+x.Source).CompareTo(y.Key+" "+y.Source); });
// Process the merged list
// we assume that a key cannot be empty
list.Add(new Member("",0,null) ; // just for proper termination of next loop
string CurKey="" ;
int starti=-1 ; int endi=-1 ;
int startp=-1 ; int endp=-1 ;
for (int n=0;n<list.Count;n++)
{
if (list[n].Key==CurKey) { if (list[n].Source="I") endi=n ; if (list[n].Source="P") endp=n ;
else
{
if (CurKey!="" )
{ // -------- Process the CurKey for matches ---------
// The Prod records corresponding to CurKey are given by list[p].dataobject whith p from startp to endp
// The Inventory records corresponding to CurKey are given by list[i].dataobject whith i from starti to endi
// if either starti or startp is negative, there is no match
... // insert your business code there
}
if (list[n].Source="I") { starti=endi=n ; startp=endp=-1 ; }
if (list[n].Source="P") { starti=endi=-1 ; startp=endp=n ; }
}