我正在开发SQL Server 2012 Express和开发人员版(带有最新的Service Pack)解决方案。
在我的数据库中,我有一个包含代码的表CODES
。此表格的FLAG
列表示代码已已打印,已读或已弃用。代码按另一列LEVEL
分组。 CODES
表格为CODE
,LEVEL
为主键。
我要快速更新表CODES,如果我SELECT COUNT(code) FROM CODES WHERE FLAG=1
要读取所有代码,有时我会阻止该表,当我们有很多行时,{{1} CPU达到100%。
所以,我有另一个表SELECT COUNT
来存储已打印,读取或删除的STATISTICS
个。当我更新codes
表中的行时,我将1添加到CODES
表。我试过这两种方式:
在更新STATISTICS
表后使用UPDATE
语句。
CODES
在CODES表中使用declare @printed bigint;
set @printed = (Select CODES_PRINTED from STADISTICS where LEVEL = @level)
if (@printed is null)
begin
insert dbo.STADISTICS(LEVEL, CODES_PRINTED) values (@level, 1)
end
else
begin
update dbo.STADISTICS set CODES_PRINTED = (@printed + 1) where LEVEL = @level;
end
。
TRIGGER
但在这两种情况下我都丢失了数据。运行我的程序后,我检查ALTER trigger [dbo].[UpdateCodesStatistics] on [dbo].[CODES]
after update
as
SET NOCOUNT ON;
if UPDATE(FLAG)
BEGIN
declare @flag as tinyint;
declare @level as tinyint;
set @flag = (SELECT FLAG FROM inserted);
set @level = (SELECT LEVEL FROM inserted);
-- If we have printed a new code
if (@flag = 1)
begin
declare @printed bigint;
set @printed = (Select CODES_PRINTED from STADISTICS where LEVEL = @level)
if (@printed is null)
begin
insert dbo.STADISTICS(LEVEL, CODES_PRINTED) values (@level, 1)
end
else
begin
update dbo.STADISTICS set CODES_PRINTED = (@printed + 1) where LEVEL = @level;
end
end
END
表格和CODES
表格并且统计数据不匹配:STATISTICS
中的打印代码和读取代码少于STATISTICS
表
这是我现在正在使用的CODES
表:
STATISTICS
顺便说一下,我很快就会更新和插入(一分钟内超过1200行)。
知道发生了什么或者我怎样才能做得更好?
答案 0 :(得分:0)
inserted
and deleted
可以包含多个(或无)行。所以像set @flag = (SELECT FLAG FROM inserted)
这样的习语从根本上被打破了。根据您的描述,听起来indexed view可能对您有用,例如:
CREATE VIEW dbo.Statistics
WITH SCHEMABINDING
AS
SELECT LEVEL, COUNT_BIG(*) as CODES_PRINTED
FROM dbo.Codes
WHERE Flag = 1
GROUP BY LEVEL
和
CREATE UNIQUE CLUSTERED INDEX IX_Statistics ON dbo.Statistics (LEVEL)
现在SQL Server将(在幕后)自动维护这些数据,您不必编写任何触发器(或显式维护单独的表)