Повышение производительности таблицы журналов в SQL Server 2005 - PullRequest
0 голосов
/ 10 октября 2009

У меня есть таблица «истории», где я регистрирую каждый запрос в веб-обработчике на нашем веб-сайте. Вот определение таблицы:

/****** Object:  Table [dbo].[HistoryRequest]    Script Date: 10/09/2009 17:18:02 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[HistoryRequest](
    [HistoryRequestID] [uniqueidentifier] NOT NULL,
    [CampaignID] [int] NOT NULL,
    [UrlReferrer] [nvarchar](512) NOT NULL,
    [UserAgent] [nvarchar](512) NOT NULL,
    [UserHostAddress] [nvarchar](15) NOT NULL,
    [UserHostName] [nvarchar](512) NOT NULL,
    [HttpBrowserCapabilities] [xml] NOT NULL,
    [Created] [datetime] NOT NULL,
    [CreatedBy] [nvarchar](100) NOT NULL,
    [Updated] [datetime] NULL,
    [UpdatedBy] [nvarchar](100) NULL,
 CONSTRAINT [PK_HistoryRequest] PRIMARY KEY CLUSTERED 
(
    [HistoryRequestID] 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

ALTER TABLE [dbo].[HistoryRequest]  WITH CHECK ADD  CONSTRAINT [FK_HistoryRequest_Campaign] FOREIGN KEY([CampaignID])
REFERENCES [dbo].[Campaign] ([CampaignId])
GO

ALTER TABLE [dbo].[HistoryRequest] CHECK CONSTRAINT [FK_HistoryRequest_Campaign]
GO

37 секунд для 1050 строк этого оператора:

SELECT * 
  FROM HistoryRequest AS hr 
 WHERE Created > '10/9/2009'
 ORDER BY Created DESC

Есть ли у кого-нибудь предположения, чтобы ускорить это? У меня есть кластерный индекс на ПК и обычный индекс на столбце CREATED. Я попробовал уникальный индекс, и он возмутился, жалуясь, что где-то есть повторяющаяся запись - чего и следовало ожидать.

Любые идеи приветствуются!

Ответы [ 4 ]

4 голосов
/ 10 октября 2009

Вы запрашиваете все столбцы (*) по непокрытому индексу (создан). Для большого набора данных вы гарантированно достигнете критической точки индекса , где сканирование кластерного индекса более эффективно, чем поиск диапазона некластеризованного индекса и поиск закладок.

Тебе нужен * всегда? Если да, и если типичный шаблон доступа подобен этому, вы должны соответствующим образом организовать таблицу и сделать Created крайним левым кластеризованным ключом.

Если нет, то подумайте об изменении вашего запроса на совместимый запрос, например. выберите только HistoryRequestID и Created, которые охватываются некластеризованным индексом. Если требуется больше полей, добавьте их в качестве включенных столбцов в некластеризованный индекс, но учтите, что это добавит дополнительное пространство памяти и время записи журнала ввода-вывода.

1 голос
/ 10 октября 2009

Эй, я видел странное поведение при извлечении столбцов XML в больших наборах. Попробуйте поместить свой индекс на Created back, затем укажите столбцы в вашем операторе select; но опустите XML. Посмотрите, как это влияет на время возврата результатов.

1 голос
/ 10 октября 2009

Для таблицы журнала вам, вероятно, не нужен столбец uniqueidentifier. Вы также вряд ли сделаете запрос по нему, так что это не хороший кандидат для кластерного индекса. Ваш пример запроса на "Создан", но там нет индекса. Если вы часто запрашиваете диапазоны значений «Создано», это будет хорошим кандидатом для кластеризации, даже если оно не обязательно уникально.

OTOH, внешний ключ предлагает частые запросы со стороны Campaign, и в этом случае может иметь смысл кластеризация, выполняемая этим столбцом, а также, вероятно, лучше распределить вставленные ключи в индексах - и суррогатный ключ, и временная метка будет добавлять записи в последовательном порядке, что требует больше времени для вставок, поскольку сектора узлов заполнены менее случайным образом.

Если это просто таблица журнала, почему в ней есть столбцы аудита обновлений? Обычно это только для записи.

0 голосов
/ 10 октября 2009

Перестроить индексы. Используйте предложение WITH (NOLOCK) после имен таблиц, где это уместно, это, вероятно, применимо, если вы хотите запускать длинные (ish) запросы к таблице, которые интенсивно используются в реальной среде (например, в файле журнала). По сути, это означает, что ваш запрос пропускает некоторые из самых последних записей, но вы также не держите открытую блокировку таблицы - что создает дополнительные накладные расходы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...