首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

小弟我有个视图,去年是0秒,今年变慢了要3-5秒。请大侠小爱和各路大侠帮忙看看啊

2013-08-13 
我有个视图,去年是0秒,今年变慢了要3-5秒。请大侠小爱和各路大侠帮忙看看啊。我写的视图很烂,还请大侠们费心

我有个视图,去年是0秒,今年变慢了要3-5秒。请大侠小爱和各路大侠帮忙看看啊。
我写的视图很烂,还请大侠们费心看看。



SELECT     dbo.Today.Task AS TaskDescr, dbo.Today.No, dbo.Today.Downno, 
                      dbo.Today_2.time4 AS time4, dbo.Today.Via AS bypass, dbo.Today.Hos AS Hos, 
                      dbo.Today.time1 AS time1, dbo.Today.time2 AS time2, 
                      dbo.Today.time5 AS Time5, dbo.Today.time3 AS time3, 
                      dbo.Today.Area AS area, '出' AS io, dbo.Today.Status, 
                      CASE WHEN dbo.Today.ber < 0 THEN '' WHEN dbo.Today.ber IN (1) THEN '南' + CONVERT(varchar, 
                      dbo.Today.ber) WHEN dbo.Today.ber > 17 THEN '北' + CONVERT(varchar, dbo.Today.ber) 
                      ELSE CONVERT(varchar, dbo.Today.ber) END AS Ber, dbo.Today.Gate AS Gate, 
                      dbo.Today.Pla AS Pla, dbo.Today.type,  
                      dbo.Reason.ReasonCN AS DisplayReason, CASE WHEN ltrim(rtrim(dbo.Today.Memo)) = '' AND 
                      ltrim(rtrim(dbo.Today.StatMemo)) <> '' THEN dbo.TodayD.StatMemo WHEN ltrim(rtrim(dbo.Today.Memo)) 
                      <> '' AND ltrim(rtrim(dbo.Today.StatMemo)) 
                      = '' THEN dbo.Today.Memo WHEN ltrim(rtrim(dbo.Todays.Memo)) <> '' AND 


                      ltrim(rtrim(dbo.Today.StatMemo)) 
                      <> '' THEN dbo.Today.Memo + ',' + dbo.Today.StatMemo WHEN ltrim(rtrim(dbo.Today.Memo)) = '' AND
                       ltrim(rtrim(dbo.Today.StatMemo)) = '' THEN '' END AS Remark, ISNULL(dbo.f_MergeVipName(dbo.Today.No, 
                      N'出', dbo.Today.Opday), N'') AS vipinfo, dbo.Today.lines
FROM         dbo.Today LEFT OUTER JOIN
                      dbo.Reason ON dbo.Today.PublishReason = dbo.Reason.ReasonID LEFT OUTER JOIN
                      dbo.Today_2 ON dbo.Today.Downno = dbo.Today_2.no
WHERE     (dbo.Today.Task NOT IN ('货A', '货B'))





这里的dbo.Today和dbo.Today_2都分别只有100多条的记录。字段也差不多都是35个。dbo.Reason里面是31条记录,6个字段。



dbo.f_MergeVipName,这个函数如下:


set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER function [dbo].[f_MergeVipName](@no nvarchar(20),@Io nvarchar(20),@Opday Datetime)
returns nvarchar(Max)
as
begin
declare @r nvarchar(Max)
set @r=''

select @r=@r+';'+( Name+','+ Class) from Vip where no=@no and Io = @Io and [Date]=@opday

return stuff(@r,1,1,'')
end



会不会是视图里面的memo判断导致的?还是这个dbo.f_MergeVipName函数导致的?


若是函数导致的,我测试了select Name+','+ Class as test from Vip where no like '%%' and Io = '出' and [Date]='2013-07-25',执行时间是0秒。
这个VIP表里有2万1千条记录,但是每天的记录也就10几条,很少的。



是在客户端用SQL SERVER 2005连接到服务器上,用select * from view去执行的视图,

这是最新刚刚执行的,执行了10次,花费时间如下,单位为秒。
5,5,5,2,4,3,3,3,3,2


去掉dbo.f_MergeVipName,这个函数以后,貌似会快1秒左右。但是去掉的话,也不是个办法啊,客户要看啊。除非把该表改一改,只提供当天的,历史的每天自动保存到专门的历史表里了。



服务器配置如下,比较低端啊:

IBM X3550M2  机架式服务器(至强四核E5504一个 4G内存 146GB热插拔SAS硬盘)




一般情况下是100多个客户端,高峰时可能有200以上,客户端程序30秒刷新一次该视图。




跪求各路大侠分析一下,变慢的可能的原因在哪里呢?





[解决办法]
SORRY,应该是:
create index  test_vip_idx on vip([Date],[No],[io])  INCLUDE(NAME,CLASS)
你可以把非聚集索引理解成是,另外一张表,与原来的数据表没有关系。唯一的关系是在索引的每行记录最后,存储了一个rowid字段,指向原来的数据表的相应记录。
想了解INCLUDE,得首先知道索引的存储结构。不管是聚集还是非聚集索引,都是平衡树结构。
没有INCLUDE的非聚集索引,叶子结点只包含索引键([Date],[No],[io]);
有INCLUDE的非聚集索引,除了索引键,还包含了另外的数据(NAME,CLASS);
当索引查找时,只会根据索引键查找,当查找到需要的数据后,就可以从INCLUDE的数据中直接取出想要的数据;否则,还要再去和数据表关联,从中取出NAME,CLASS字段。
[解决办法]
标记下,明天看看

热点排行