获取表统计信息的更好方法

时间:2014-11-25 07:40:09

标签: sql sql-server indexed-view

我正在开发SQL Server 2012 Express和开发人员版(带有最新的Service Pack)解决方案。

在我的数据库中,我有一个包含代码的表CODES。此表格的FLAG表示代码已已打印已读已弃用。代码按另一列LEVEL分组。 CODES表格为CODELEVEL主键

我要快速更新表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行)。

知道发生了什么或者我怎样才能做得更好?

1 个答案:

答案 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将(在幕后)自动维护这些数据,您不必编写任何触发器(或显式维护单独的表)