以前写的一个sql语句,由于数据量很大后查询的速度非常慢,其主要原因是由一个函数导致的
CREATE function f_str(@name int) returns varchar(1000) as begin declare @ret varchar(1000) select @ret=isnull(@ret,'')+CompartmentCode+"-" from InCompartment where ICGroupId=@name return @ret end 这个函数就是把查询出的数据的CompartmentCode用 - 连接符连接起来
在查询的时候,在sql语句中有个子查询语句
SELECT ICGroupId, COUNT(ICGroupId) AS CheShu, value = dbo.f_str(ICGroupId) FROM InCompartment GROUP BY ICGroupId
用来统计 ICGroupId 的相关数据 ,由于用到了连接函数导致查询非常的缓慢,在数据量变大后要等很久而主要的查询的,发现InCompartment这个表读取的次数非常大
表 'CheckDep'。扫描计数 0,逻辑读 0 次,物理读 0 次,预读 0 次。 表 'UnloadSite'。扫描计数 99,逻辑读 198 次,物理读 0 次,预读 0 次。 表 'SendCompany'。扫描计数 100,逻辑读 200 次,物理读 0 次,预读 0 次。 表 'Station'。扫描计数 100,逻辑读 200 次,物理读 0 次,预读 0 次。 表 'Goods'。扫描计数 99,逻辑读 198 次,物理读 0 次,预读 0 次。 表 'InCompartment'。扫描计数 2,逻辑读 15765 次,物理读 0 次,预读 0 次。 表 'ReceiveCompany'。扫描计数 1,逻辑读 2 次,物理读 0 次,预读 0 次。 表 'InCompartmentGroup'。扫描计数 1,逻辑读 354 次,物理读 0 次,预读 0 次。 表 'InTrain'。扫描计数 1,逻辑读 221 次,物理读 0 次,预读 0 次。
预执行成本占用非常高
而这一切都是由于上面提到的函数引起的。
所以需要对上面那个查询语句得出的结果如何快速的查询出来。
这里我想到的是把需要查询的内容存到一个表中,然后根据InCompartment的编号做触发器。这样就只需要查询表就行了,而不用去做过多的字符串连接操作
首先创建一个表
alter table isnum ( ICGroupId int, CheShu int, value varchar(1000) )
然后把历史的数据全部的转存到isnum表中
insert into isnum SELECT ICGroupId, COUNT(ICGroupId) AS CheShu, value = dbo.f_str(ICGroupId) FROM InCompartment GROUP BY ICGroupId
最后给InCompartment添加一个触发器
CREATE TRIGGER P_isnum ON [dbo].[InCompartment] FOR INSERT, UPDATE, DELETE AS --删除与之相关的数据 delete from isnum where ICGroupId in(select deleted.ICGroupId from deleted UNION SELECT inserted.ICGroupId from inserted ) --创建一条和ICgroupID相关的数据 insert into isnum select ICGroupId, COUNT(ICGroupId) AS CheShu, value = dbo.f_str(ICGroupId) FROM InCompartment where ICgroupId in (select deleted.ICGroupId from deleted UNION SELECT inserted.ICGroupId from inserted ) GROUP BY ICGroupId这样由于字符串连接的查询字符串就可以直接查isnum就可以得到所要的结果
select ICGroupId,CheShu,[value] from isnum