有二个表.表BOM数据量非常大.现是400W左右.表二PnoStatus数据不大.现只有50条左右.
都是自增主键.表BOM主键为IDNO,相关列有Pno(这个每Pno可能有3000多个相同的.),ldate(为数据插入时自动取当取时间).
表PnoStatus有主建ID,相关列有Pno,UpdateTime,Status.
表BOM每隔一个小时都会导入新数据(每次大约3000条,相同pno).因相关要求.导入时更新相关表PnoStatus.
规则就是在PnoStatus的Pno等于BOM的pno取最大ldata.然后比较PnoStatus的UpdateTime,后更新Status.
最开始,按语意自然如下处理.
db.PnoStatus.ToList().ForEach(t => { var maxdate = db.BOM.Where(p => p.PNo == t.Pno) .Max(p => p.ldate); if (t.UpdateTime > mdate) t.Status = "Blue"; else t.Status = "Red"; });
这样处理后发现整个处理完要完时间8分钟左右.现暂时还不影响.但是PnoStatus数据变多后恐出问题.
先查看这个语句.
select max(a.ldate) from BOM as a where a.PNo = 'Sdf00000001'
这条数据处理就要求10S左右.50条语句就500S.差不多是时间8分钟.
结合前几天看的HashTable的原理.我自己推断如下.索引查找和表的数据多少没有关系都是O(1)次查找.我先在表Bom
上想建立关于PNo的索引.那想给出相关错误.没有成功.
最后我在默认索引上IDNO上想办法.想查找对应Pno的最大时间.而时间和IDNO有个明显关系.IDNO越大.时间只会更大.不会更少.(表
BOM不会编辑数据,只会导入数据.)写出如下SQL.
select ldate from BOM where IDNO = ( select max(IDNO) from BOM as a where a.PNo = 'Sdf00000001' )
说实话.我刚写出来没想有什么效果.在我认为这完全是把简单问题复杂化了.但是我执行了下.显示1S!!
相应的现在整个时间44S就全部完成.
对应过程:
可以看到第二个查询SQL还进行了并行处理都要12S.而第一个虽然复杂.但是时间短.
整个过程自己都还相对不是很明白.感觉有很大的巧合性.SQL也不是我的专长.唯一肯定索引相对平常查找优势太明显.希望给园友一点参考.
几天后.我感到还是有点疑惑.试了如下二语句.
select max(IDNO) from BOM as a where a.PNo = 'Sdf00000001' select IDNO from BOM as a where a.PNo = 'Sdf00000001'
发现第二条语句也还是10S左右,没有什么区别.分析插入数据时.ldate插入时都是一样.而IDNO是自增的不一样.就这点而导致二条语句取Max(IDNO OR ldate)是产生10倍差.
原先在我想法中.取Max(IDNO)的值时会先把所有的IDNO取出来的再比较也是错误的.
他取Max(IDNO)时应没有取出相关的IDNO而得到最大值.不过有个新的问题出来了.他是如何取最大值的?
可惜我不知道是否相关工具能查看到具体过程.希望有相关高手能提示下.