2014-11-25 2 views
0

Я разрабатываю SQL Server 2012 Express и версию разработчика (с последним пакетом обновления).Лучший способ получить статистику таблицы

В моей базе данных У меня есть таблица CODES с кодами. Эта таблица имеет FLAG столбец , указывающий, что код был напечатан , чтения или упал. Коды сгруппированы по другой колонке, LEVEL. CODES Таблица имеет CODE и LEVEL как первичный ключ.

Я собираюсь обновить таблицу КОДЫ очень быстро, и если я SELECT COUNT(code) FROM CODES WHERE FLAG=1, чтобы получить все коды чтения, когда-нибудь, я блокирую эту таблицу, и когда у нас есть много много строк, SELECT COUNT CPU идет до 100%.

Итак, у меня есть другой стол, STATISTICS для хранения, сколько codes было напечатано, прочитано или опущено. Когда я обновляю строку в таблице CODES, я добавляю таблицу от 1 до STATISTICS. Я пробовал это двумя способами:

С сообщением UPDATE после обновления таблицы 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 таблица, в которой я использую сейчас:

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 

Кстати, я обновляю и вставив очень быстро (более 1200 строк в минуту).

Любая идея, что происходит или как я могу сделать это лучше?

ответ

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 будет (за кадром) сохранить эти данные автоматически и вам не нужно писать какие-либо триггеры (или явно поддерживать отдельную таблицу).

+0

Спасибо за ваш ответ. Если мне нужна статистика для чтения и удаления кодов, нужны ли мне еще два индексированных представления? – VansFannel

+0

Это зависит - я понятия не имею, каковы ваши данные: вы бросаете фразы типа 'read',' drop' и 'print', но все, что у меня есть, это ваш существующий код, который, похоже, работает в терминах столбцов «Флаг» и «Уровень».Возможно, что все статистические данные будут существовать в одном индексированном представлении, или вам может понадобиться несколько представлений. Как я уже сказал, я не знаю вашу модель данных, поэтому в настоящее время не могу дать более подробные рекомендации. –

+0

Я думаю, что индексированные представления могут повлиять на производительность записи. Кроме того, они также могут вызывать другие проблемы. Например, если одна или несколько базовых таблиц подвержены частым обновлениям, то, в зависимости от агрегаций, которые мы выполняем в индексированном представлении, возможно, что мы увеличим конфликт блокировок в индексе представления. Таким образом, это не лучшее решение. – VansFannel

Смежные вопросы