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

sgyiliya 2013-08-01 11:11:38
我写的视图很烂,还请大侠们费心看看。



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秒刷新一次该视图。




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




...全文
247 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
sgyiliya 2013-08-11
  • 打赏
  • 举报
回复
引用 10 楼 Beirut 的回复:
标记下,明天看看
谢谢各路大侠。最终是新建了个VIP历史表,把2013年之前的记录转移到历史表里去。目前VIP表记录数为2100条左右。计划今后每半年或一年转移一次。相关的查询历史的代码要做些修改。
黄_瓜 2013-08-07
  • 打赏
  • 举报
回复
标记下,明天看看
sgyiliya 2013-08-01
  • 打赏
  • 举报
回复
引用 3 楼 wwwwgou 的回复:
--today, reason, today_2数据量很少,全表扫描没有问题
--Vip表加索引: [Date],[No],[io] INCLUDE(NAME)
--如果还不行
SET STATISTICS IO, TIME ON
查看实际的执行计划,分析一下
是执行这句是吗? create index test_vip_idx on vip([Date],[No],[io]) INCLUDE(NAME) 能不能解释一下include,我百度了一下,不是很理解,而且为什么Class字段又不要include呢?
vb_vs 2013-08-01
  • 打赏
  • 举报
回复
引用 2 楼 sgyiliya 的回复:
[quote=引用 1 楼 vb_vs 的回复:] 1 看看硬件瓶颈。 数据库服务器很吃资源的。 你的内存4GB稍微不足。 2 看看你的iddex 可能你数据量多了,所以速度变慢了。 3 优化一下你的sql script.看的出来有不少要优化的哈
iddex是什么?我不懂啊,能说详细点吗? 要优化哪些?能详细说说吗?[/quote] INDEX
Shawn 2013-08-01
  • 打赏
  • 举报
回复
用“活动和监视器”看一下资源的阻塞情况。你的系统可能会存在内存不足,而导出频繁从硬盘上读数据的可能性。
Shawn 2013-08-01
  • 打赏
  • 举报
回复
--today, reason, today_2数据量很少,全表扫描没有问题
--Vip表加索引: [Date],[No],[io] INCLUDE(NAME)
--如果还不行
SET STATISTICS IO, TIME ON
查看实际的执行计划,分析一下
sgyiliya 2013-08-01
  • 打赏
  • 举报
回复
引用 1 楼 vb_vs 的回复:
1 看看硬件瓶颈。 数据库服务器很吃资源的。 你的内存4GB稍微不足。 2 看看你的iddex 可能你数据量多了,所以速度变慢了。 3 优化一下你的sql script.看的出来有不少要优化的哈
iddex是什么?我不懂啊,能说详细点吗? 要优化哪些?能详细说说吗?
vb_vs 2013-08-01
  • 打赏
  • 举报
回复
1 看看硬件瓶颈。 数据库服务器很吃资源的。 你的内存4GB稍微不足。 2 看看你的iddex 可能你数据量多了,所以速度变慢了。 3 优化一下你的sql script.看的出来有不少要优化的哈
發糞塗牆 2013-08-01
  • 打赏
  • 举报
回复
有执行计划看看不?
Shawn 2013-08-01
  • 打赏
  • 举报
回复
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字段。
vb_vs 2013-08-01
  • 打赏
  • 举报
回复
index 就是创建另外一个表,按照一定顺序来排列你的index的column. 当运行时,系统会先到你的index表里去寻找符合的值。然后根据index表里的地址,去找你实际的row. include就是在你的index里包含一些column, 然后如果你的index表里已经有了你所需要的数据,那么你是不是省了下一步了。那么这么做就提高了搜索的效率。

22,206

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧