.net – 如何使用Join连接PLINQ现有的LINQ查询?
我正在使用LINQ来比较两个DataSet,以创建新的行并更新现有的.我注意到完整的比较持续约1.5小时,两个内核中只有一个内核正忙(任务管理器占用CPU的使用率为50-52%).我必须承认,我对并行LINQ是全新的,但我认为它可以显着提高性能.
所以我的问题是,如何和什么应该并行化? 这些是原始查询(缩写为必需): 'check for new data Dim srcUnique = From row In src.Email_Total Select Ticket_ID = row.ticket_id,Interaction = row.interaction,ModifiedAt = row.modified_time Dim destUnique = From row In dest.ContactDetail Where row.ContactRow.fiContactType = emailContactType.idContactType Select row.ContactRow.Ticket_ID,row.Interaction,row.ModifiedAt 'get all emails(contactdetails) that are in source but not in destination Dim diffRows = srcUnique.Except(destUnique).ToList 'get all new emails(according to ticket_id) for calculating contact columns Dim newRowsTickets = (From row In src.Email_Total Join d In diffRows On row.ticket_id Equals d.Ticket_ID _ And row.interaction Equals d.Interaction _ And row.modified_time Equals d.ModifiedAt Group row By Ticket_ID = row.ticket_id Into NewTicketRows = Group).ToList For Each ticket In newRowsTickets Dim contact = dest.Contact.FindByTicket_IDfiContactType(ticket.Ticket_ID,emailContactType.idContactType) If contact Is Nothing Then ' Create new Contact with many sub-queries on this ticket(omitted) ****' Dim newContact = Me.dest.Contact.NewContactRow dest.Contact.AddContactRow(newContact) contact = newContact Else ' Update Contact with many sub-queries on this ticket(omitted) ' End If daContact.Update(dest.Contact) ' Add new ContactDetail-Rows from this Ticket(this is the counterpart of the src.Email_Total-Rows,details omitted) ' For Each newRow In ticket.NewTicketRows Dim newContactDetail = dest.ContactDetail.NewContactDetailRow newContactDetail.ContactRow = contact dest.ContactDetail.AddContactDetailRow(newContactDetail) Next daContactDetails.Update(dest.ContactDetail) Next 注意:daContact和daContactDetails是SqlDataAdapters,source和dest是DataSet,Contact和ContactDetail是DataTable,每个ContactDetail都属于一个Contact. 即使不是这两个核心都不会使用100%的CPU,我认为如果我并行化查询,那么它会显着提高性能,因为第二个核心几乎处于空闲状态.对于每一个都可能是一个优化的地方,因为票不相关.所以我假设我可以循环多个线程并创建/更新记录并行.但是如何使用PLINQ? 侧面注意:正如我在评论中提到的,性能不是我迄今为止的关键因素,因为服务器的唯一目的是同步MySQL数据库(在另一台服务器上)与MS SQL Server(在同一台服务器上)作为这个Windows服务).它作为由另一个服务生成的报告的来源.但这些报告只能每天生成一次.但除此之外,我有兴趣学习PLINQ,因为我认为这可能是一个很好的锻炼. 如果不清楚,我会相应地更新我的答案.提前致谢. 编辑:这是我调查和尝试的结果: 问题:如何使用联接“PLINQ”现有的LINQ查询? Answer:请注意,一些LINQ运算符是二进制的,它们以两个IEnumerables为输入.加入是这样一个运算符的完美例子.在这些情况下,最左侧数据源的类型决定是使用LINQ还是PLINQ.因此,您只需要在第一个数据源上调用AsParallel,使您的查询并行运行: IEnumerable<T> leftData = ...,rightData = ...; var q = from x in leftData.AsParallel() join y in rightData on x.a == y.b select f(x,y); 但是如果我以下列方式更改查询(请注意AsParallel): Dim newRowsTickets = (From row In src.Email_Total.AsParallel() Join d In diffRows On row.ticket_id Equals d.Ticket_ID _ And row.interaction Equals d.Interaction _ And row.modified_time Equals d.ModifiedAt Group row By Ticket_ID = row.ticket_id Into NewTicketRows = Group).ToList 编译器会抱怨我需要将AsParallel添加到正确的数据源.所以这似乎是一个VB.NET问题或缺乏文档(文章来自2007).我认为后者是因为(除了那个可推荐的)文章还说你需要手动添加System.Concurrency.dll,但实际上它是.NET 4.0 Framework和命名空间Sytem.Threading.Tasks的一部分. 我意识到我不会从并行获利.除了在顺序模式下查询足够快(即使两个集合中几乎相同的行数导致最大的比较数量,我得到的结果不到30秒).但是,为了完整起见,我会补充一下. 所以我决定并行化每个与LINQ-Queries一样简单的东西,你只需要在最后添加AsParallel(). 现在,两个内核都在同一时间工作,但CPU占用率仍然保持在54%. 所以这是PLINQ版本到目前为止 Dim diffRows = srcUnique.AsParallel.Except(destUnique.AsParallel).ToList Dim newRowsTickets = (From row In src.Email_Total.AsParallel() Join d In diffRows.AsParallel() On row.ticket_id Equals d.Ticket_ID _ And row.interaction Equals d.Interaction _ And row.modified_time Equals d.ModifiedAt Group row By Ticket_ID = row.ticket_id Into NewTicketRows = Group).ToList For Each ticket In newRowsTickets. AsParallel(). WithDegreeOfParallelism(8). WithExecutionMode(ParallelExecutionMode.ForceParallelism) ' blah,blah ... ' 'add new ContactDetails for this Ticket(only new rows) For Each newRow In ticket.NewTicketRows. AsParallel(). WithExecutionMode(ParallelExecutionMode.Default) ' blah,blah ... ' Next daContactDetails.Update(dest.ContactDetail) Next 不幸的是,与顺序模式相比,使用AsParallel没有任何性能优势: 对于每个与AsParallel(hh:mm:ss.mm): 09/29/2011 18:54:36: Contacts/ContactDetails created or modified. Duration: 01:21:34.40 没有: 09/29/2011 16:02:55: Contacts/ContactDetails created or modified. Duration: 01:21:24.50 有人可以解释一下这个结果吗?数据库的写入访问是否为每个负责类似的时间? 以下是推荐读物: > http://msdn.microsoft.com/en-us/magazine/cc163329.aspx(不可更新) > List of changes since above article > Overview of videos/articles according this topic 解决方法有3点值得进一步调查,>不要使用.toList().我可能是错的,但我认为使用.ToList 我不认为你在插入时会获得PLinq的优势.查看this answer了解更多详情. 希望有帮助.如果您需要澄清以上任何一点,请咨询. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |