2014-11-25 2 views
0

SQL Server 2012 Express 및 개발자 버전 (최신 서비스 팩 포함) 솔루션을 개발 중입니다.테이블 통계를 얻는 더 좋은 방법

내 데이터베이스에는 코드가있는 CODES 테이블이 있습니다. 이 테이블은이 코드 인쇄되었음을를 나타내는 FLAG을 가지고 읽거나 떨어졌다. 코드는 다른 열, LEVEL에 의해 그룹화됩니다. CODES 테이블은 CODELEVEL기본 키입니다.

테이블 코드를 매우 빨리 업데이트하려고합니다. 모든 코드를 읽으려면 SELECT COUNT(code) FROM CODES WHERE FLAG=1을 읽으십시오. 언젠가는 해당 테이블을 차단하고 많은 행이있을 때 SELECT COUNT CPU가 100 %로 이동합니다.

그래서 codes이 얼마나 많은 수의 데이터를 인쇄했는지, 읽었는지, 저장했는지 등을 나타내는 STATISTICS 테이블이 있습니다. CODES 테이블에서 행을 업데이트하면 STATISTICS 테이블에 1을 더합니다. 나는이 두 가지 방법을 시도했다.

CODES 테이블을 업데이트 한 후 UPDATE 문을 사용한다.

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 

CODES 테이블에 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 테이블보다 적습니다. 내가 업데이트하고 (분에서 1200 개 이상의 행을) 매우 신속하게 삽입하고있어, 그런데

CREATE TABLE [dbo].[BATCH_STATISTICS](
    [CODE_LEVEL] [tinyint] NOT NULL, 
    [CODES_REQUESTED] [bigint] NOT NULL CONSTRAINT [DF_BATCH_STATISTICS_CODES_REQUESTED] DEFAULT ((0)), 
    [CODES_PRINTED] [bigint] NOT NULL CONSTRAINT [DF_BATCH_STATISTICS_CODES_PRINTED] DEFAULT ((0)), 
    [CODES_READ] [bigint] NOT NULL CONSTRAINT [DF_BATCH_STATISTICS_CODES_READ] DEFAULT ((0)), 
    [CODES_DROPPED] [bigint] NOT NULL CONSTRAINT [DF_BATCH_STATISTICS_CODES_DROPPED] DEFAULT ((0)), 
    [CODES_NOREAD] [bigint] NOT NULL CONSTRAINT [DF_BATCH_STATISTICS_CODES_NOREAD] DEFAULT ((0)), 
CONSTRAINT [PK_BATCH_STATISTICS] PRIMARY KEY CLUSTERED 
(
    [CODE_LEVEL] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

:

내가 지금 사용하고 STATISTICS 테이블입니다.

어떤 일이 벌어 지는지 또는 어떻게 개선 할 수 있습니까?

답변

0

inserted and deleted는 여러 (또는 않음) 행을 포함 할 수있다. 따라서 set @flag = (SELECT FLAG FROM inserted)과 같은 관용구는 근본적으로 손상되었습니다.

CREATE VIEW dbo.Statistics 
WITH SCHEMABINDING 
AS 
    SELECT LEVEL, COUNT_BIG(*) as CODES_PRINTED 
    FROM dbo.Codes 
    WHERE Flag = 1 
    GROUP BY LEVEL 

과 : 당신의 설명에서, 그것은, 대신 당신을 위해이 같은 일을 수있는 indexed view 같은 소리 (뒤에서) 자동으로 데이터를 유지

CREATE UNIQUE CLUSTERED INDEX IX_Statistics ON dbo.Statistics (LEVEL) 

이제 SQL 서버와 트리거를 작성하거나 별도의 테이블을 명시 적으로 작성할 필요가 없습니다.

+0

답장을 보내 주셔서 감사합니다. 읽고 쓰는 코드에 대한 통계를 원한다면 인덱싱 된 뷰가 2 개 더 필요합니까? – VansFannel

+0

- 당신의 데이터가 어떻게 생겼는지는 모르겠다. 당신은'read','dropped','printed'와 같은 문구를 던져 버리는 것이지만, 기껏해야 여러분의 기존 코드는 열의 관점에서 작동하는 것 같습니다. '깃발'과'수준'이라고 칭한.모든 통계가 단일 색인보기에 존재하거나 여러보기가 필요할 수도 있습니다. 내가 말했듯이, 나는 당신의 데이터 모델을 모른다. 그래서 지금은 더 나은 조언을 제공 할 수 없다. –

+0

인덱스 된 뷰는 쓰기 성능에 영향을 미칠 수 있다고 생각합니다. 또한, 그들은 또한 다른 문제를 일으킬 가능성이 있습니다. 예를 들어, 하나 이상의 기본 테이블이 자주 갱신되는 경우, 인덱스 된 뷰에서 수행하는 집계에 따라 뷰의 인덱스에서 잠금 경합을 증가시킬 수 있습니다. 그래서, 이것은 더 나은 해결책이 아닙니다. – VansFannel

관련 문제