有一个数据库,结构如上图所示。
每天2个时次dt*70个站点Vjdm*60个要素Yksu*20个预报时次Sc的值Uuju一共16万个入库的数据。
入库可以提前入,所以时间效率不用管,而且可以用VS2015的多线程,所以很容易达到速度的极限。
检索是按照若干dt,Vjdm,Yksu的组合检索出[Sc Uuju]来。而且dt常用的就是最近入库的2个时次,Vjdm也只是其中最常用的4个,Yksu也是最常用的4个。其他都用的很少,不用在乎效率。
因为我不是学计算机的,整个都是用VS2015的LINQ TO SQL调用数据库的,不会写索引,视图什么的(尝试写了dt,Vjdm,Yksu3个单独的非聚集索引,毫无帮助)。200万数据开始,检索时间已经到了6秒了。这要是运行一年检索过程大概要10分钟了!!
针对检索过程,求大神支招。
以前我用LINQ to SQL来用数据库,都是用这两个工具优化的。
常常能优化的非常漂亮,经常有99%效率提高的。
但这次,弄了很多遍,都是提高0%,不给建议。
linq to sql大概是这样写的:
var k1 =
from kk in dc.JxhYb
from kk2 in dt2(数组datetime[])
from kk3 in ys3(数组string[])
from kk4 in vd4(数组string[])
where kk.dt ==kk2 &&kk.Vjdm ==kk4 &&kk.Yksu ==kk3
select kk;
你写的sql和sql的执行计划,看下
linq to sql大概是这样写的:
var k1 =
from kk in dc.JxhYb
from kk2 in dt2(datetime的数组)
from kk3 in ys3(nchar50的数组)
from kk4 in vd4(nchar50的数组)
where kk.dt ==kk2 &&kk.Vjdm ==kk4 &&kk.Yksu ==kk3
select kk;
@cxwcdxw: sqlservierprofiler可以监视sql执行情况,你执行下linq就能在监视里看见他实际生成的sql
你的linq为什么没有表连接?
@吴瑞祥: 感谢你。通过你的方法,知道我错误的地方了。
本来想这样是最高效率的
using (DataClasses1DataContext dc = new DataClasses1DataContext())
{
//全部放在sjk里面
var ksjk =
from kk in dc.JxhYb
from dt1 in dt
from ys1 in ys
where kk.Yksu == ys1.Mnzi && kk.dt == dt1
select kk;
ksjk2 = ksjk.ToArray();
}
但vs会报这个错:
“System.NotSupportedException”类型的未经处理的异常在 System.Data.Linq.dll 中发生
其他信息: 不能在查询运算符(Contains 运算符除外)的 LINQ to SQL 实现中使用本地序列。
所以,我就在3个from后面都用了.AsParallel()
这样解决了问题,但sql语言却变成了
SELECT [t0].[Id], [t0].[dt], [t0].[Vjdm], [t0].[Yksu], [t0].[Sc], [t0].[Uuju]
FROM [dbo].[JxhYb] AS [t0]
这样当然是没有效率的。
这个问题就算解决了。分给你了,感激不尽。
同时,现在问题回到,vs开始报错那块,我不能用.AsParallel(),你能帮我看下,怎么处理吗?
@cxwcdxw: 你的linq没有表连接?
@吴瑞祥: DataClasses1DataContext dc = new DataClasses1DataContext()这个链接的。
@cxwcdxw: 你得百度下表连接.
@吴瑞祥: 后面我自己解决该问题了。
前面用了asparallel以后,sql就那样select全部了。所以,就不存在优化了。
后面我自己用3个大for循环嵌套,最里面在
var k1 =
from kk in dc.JxhYb
where kk.dt== &&kk.Vjdm == &&kk.Yksu ==
select kk;
写完以后,VS(也可能是Resharper)提示我说改成这样:
ksjk2.AddRange(from dt1 in dt from vd1 in vd from ys1 in ys from vv in (from kk in dc.JxhYb where kk.dt == dt1 && kk.Vjdm == vd1.Mnzi && kk.Yksu == ys1.Mnzi select kk) select vv);
就彻底解决问题了。
然后用自动优化(自动索引、视图等等),耗时大约10-200毫秒了。
因为看见索引了,基本再多也不会有什么问题了吧。
不知道你具体的查询语句是什么样的,比你更多内容的表结构,200多万的数据都是秒查,当然,翻到10w多页的时候会慢些。
我所有语句都是LINQ to sql写的,所以具体的语句我不知道。我大概描述出来啊,不知道对不对。
首先,我的数据库,除了id主键标识外,没有任何索引视图等。
因为LINQ TO SQL是延迟执行的,所以,我每次都应该是这样检索的:
dt等于1个值或几个值
Vjdm等于1个值或几个值
Yksu等于1个或几个值
得到这些元素(linq to sql可能包含id,也可能不包含,但我不访问这个。)